我想从这个通用实用程序方法中删除所有“未经检查”的警告(具有许多类似方法的较大类的一部分)。在紧要关头,我可以使用@SuppressWarnings(“unchecked”),但我想知道我是否可以正确使用泛型来避免警告。
该方法旨在允许调用者通过传递给compareTo来比较两个对象,但是如果对象是字符串则以不区分大小写的方式执行它。
public static int compareObject(Comparable o1, Comparable o2)
{
if ((o1 instanceof String) && (o2 instanceof String))
return ((String) o1).toUpperCase().compareTo(((String) o2).toUpperCase());
else
return o1.compareTo(o2);
}
这是我第一次(不正确)尝试解决方案。参数工作正常,但是行o1.compareTo(o2)有一个编译错误“Comparable类型中的方法compareTo(capture#15-of?)不适用于参数(Comparable”。
public static int compareObject(Comparable<?> o1, Comparable<?> o2)
{
if ((o1 instanceof String) && (o2 instanceof String))
return ((String) o1).toUpperCase().compareTo(((String) o2).toUpperCase());
else
return o1.compareTo(o2);
}
有什么建议吗?
答案 0 :(得分:2)
我刚试过这个:
public static <T extends Comparable> int compareObject(T o1, T o2) {
if ((o1 instanceof String) && (o2 instanceof String))
return ((String) o1).toUpperCase().compareTo(((String) o2).toUpperCase());
else
return o1.compareTo(o2);
}
它编译,但在compareTo()调用上给出了未经检查的强制警告 我尝试将其更改为
public static <T extends Comparable<T>> int compareObject(T o1, T o2) {
并且字符串检查无法编译(“不可转换的类型:found:T,required:String”)。不过,我认为这一定很接近。
编辑:正如评论中所指出的,这是一个bug in javac。第二种形式确实是正确的,但目前不会编译。看起来很疯狂,这是没有警告的代码:
public static <T extends Comparable<T>> int compareObject(T o1, T o2) {
if (((Object) o1 instanceof String) && ((Object) o2 instanceof String))
return ((String) (Object)o1).toUpperCase().compareTo(((String) (Object)o2).toUpperCase());
else
return o1.compareTo(o2);
}
正如您所看到的,唯一的区别是Object
的所有冗余演员表。
答案 1 :(得分:1)
以下是您要找的内容:
public static <T extends Comparable<T>> int compareObject(T o1, T o2) {
if ((o1 instanceof String) && (o2 instanceof String))
return ((String) o1).toUpperCase().compareTo(((String) o2).toUpperCase());
else
return o1.compareTo(o2);
}
答案 2 :(得分:1)
我希望你知道这里的许多方法确实改变了方法的语义。使用原始方法,您可以比较不同类型的对象(如果允许),但使用
public static <T extends Comparable<T>> int compareObject(T o1, T o2)
你不能再进行这种比较了。允许这样做的变体是
public static int compareObject2(Comparable<Object> o1, Comparable<Object> o2) {
if (((Object) o1 instanceof String) && ((Object) o2 instanceof String))
return ((String) (Object)o1).toUpperCase().compareTo(((String) (Object)o2).toUpperCase());
else
return o1.compareTo(o2);
}
(我为所提到的javac bug插入了变通方法。)但这并没有增强类型安全性或任何东西,因此在这种情况下,最好使用更易理解的非泛型方法并使用@SuppressWarnings("unchecked")
。有过度使用仿制药这样的事情。
答案 3 :(得分:0)
以下内容如何:
public static <T extends Comparable<T>> int compareObjects(T o1, T o2)
{
return o1.compareTo(o2);
}
public static int compareObjects(String o1, String o2)
{
return o1.compareToIgnoreCase(o2);
}
缺点是当使用恰好是Strings的对象调用compareObjects()
时,编译器会将您的调用绑定到第一个函数,并且最终会进行区分大小写的比较。
答案 4 :(得分:-1)
您是否测试过以下内容?
public static <T> int compareObject(Comparable<T> o1, Comparable<T> o2)
{
if ((o1 instanceof String) && (o2 instanceof String))
return ((String) o1).toUpperCase().compareTo(((String) o2).toUpperCase());
else
return o1.compareTo(o2);
}
我认为它应该可以正常工作。