是否可以创建一个使用对象作为参数的方法,但是没有准确指定将传递的对象类型?该方法将尝试使用大多数对象具有的compareTo
方法。
此外,是否可以检查某个对象是否具有compareTo
方法,如果它没有,则抛出异常?
答案 0 :(得分:1)
您需要做的唯一事情就是实现Comparable
接口。 Java将确保您传入的任何内容在编译时都是类型安全的,这意味着您不必抛出任何类型的运行时异常。
从那里,您可以利用Java中的任何标准排序方法:
(请注意,对于Arrays.sort
,它需要Object[]
,但如果违反了Comparable
的合同,则会抛出异常。)
答案 1 :(得分:0)
根据你的描述,听起来像你要求的是使用铸造:
/**
* @param lhs
* @param rhs
* @return the result of comparing lhs to rhs via compareTo
* @throws NullPointerException
* if lhs or rhs is null
* @throws ClassCastException
* if lhs or rhs does not implement Comparable or
* if lhs and rhs are not mutually comparable
* @see Comparable#compareTo(Object)
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private static int compareByCasting(Object lhs, Object rhs) {
Comparable compL = (Comparable) lhs;
Comparable compR = (Comparable) rhs;
return compL.compareTo(compR);
}
This is how methods like Arrays.sort
work behind the scenes.
也就是说,编写这样的代码是非常必要的,除非你像Arrays.sort
那样编写非常低级的API。 Java具有静态类型,因此通常目标是将类型检查推送到编译时进行编程,这样我们就不必运行程序来验证它是否正确。这就是我们使用接口和泛型等工具的原因。
答案 2 :(得分:-1)
具有如下约束的通用自定义方法应该使您能够比较实现通用Comparable
接口的对象,因此,无需采用类型Object
的参数,然后确保它具有某种方式compareTo
方法。
public <T extends Comparable<T>> int comparer(T thiss, T that){
// do logic
}
答案 3 :(得分:-1)
排序方法[...]一个对象数组
如果所有这些对象的类型相同且实现相似,则可以使用generics
请注意,如果类型不同,则需要编写自定义方法进行比较(即整数和字符串比较)
private <A extends Comparable<A>> void bigger(A a, A b)
{
if(a.compareTo(b) > 0)
System.out.println("a bigger");
else
System.out.println("b bigger");
}
请注意,这仅适用于相同类型的对象
//works
String a = "5";
String b = "6";
bigger(a, b);
//compile error
Integer c = 5;
String d = "6";
bigger(c, d);
这适用于实现Comparable
的内容在自定义对象上,通常可以直接实现
class Duck implements Comparable<Duck>
{
private int height;
[...]
public int compareTo(Duck other)
{
return height - other.height;
}
}
关于此问题很酷,大多数sorting bits of the Java API都是为了处理Comparable
如果您不知道它们是可比较对象并坚持将所有内容保留为对象,那么您很可能会使用Reflection
int compare(Object a, Object b) throws NoSuchMethodException, IllegalAccessException, java.lang.reflect.InvocationTargetException
{
return (Integer)a.getClass().getMethod("compareTo", b.getClass()).invoke(a, b);
}