我有一个用Java 1.4编写的旧个人项目,我正在移植到版本2的1.5(我还是新手)。除了添加新功能和重构代码之外,我还迁移到泛型集合,注释等。
有一段特殊的代码我不知道如何更改为1.5并且不想在其上添加@SuppressWarnings。它是这样的:
if (value instanceof Comparable) {
isMatch = (((Comparable) value).compareTo(selectedValue) == 0);
} else {
//fallback to equals
isMatch = selectedValue.equals(value);
}
它只是与compareTo()中的广泛匹配进行简单比较,或者如果不是Comparable类型则默认为plain equals()。
我收到了Comparable is a raw type. References to generic type Comparable<T> should be parameterized
警告。
如何将上述代码修改为1.5并清除警告。或者除了添加@SuppressWarnings之外别无选择?
答案 0 :(得分:2)
具体来说,您会收到警告,因为您需要在演员表中使用类型参数限定Comparable
。这样您就拥有((Comparable<Type>)value)
,其中Type
是({1}}类型的基本类型。
但是,即使你这样做,你仍然会收到警告。这一次,问题是编译时selectedValue
“消失”,这意味着没有办法确保该类实际上是<Type>
。您只能检查对象是否为Comparable<Type>
。请考虑以下测试应用程序:
Comparable
代码会发出警告,因为虽然class Type{
public int x = 0;
}
class Other implements Comparable {
public int compareTo(Type obj) {
return obj.x;
}
}
class Test {
public static void main(String[] args) {
Other obj1 = new Other();
Object value = obj1;
String selectedValue = "";
if (value instanceof Comparable) {
System.out.println(((Comparable<String>) value).compareTo(selectedValue));
}
}
}
为value
,但却无法与Comparable
进行比较。后者仍然是可取的,因为你至少可以检查参数是否为“预期”类型。
最后,您需要String
。
请注意,如果您希望它可以与任何类一起使用。然后你也可以保持原样(或使用@SuppressWarnings
,因为它们(在这种情况下)是等价的)。显然增加了Comparable<Object>
。
答案 1 :(得分:1)
我没有看到在没有警告的情况下编写此代码的方法。您必须将value
强制转换为Comparable<? super Value>
,因为它指定了对类型参数的限制,这是一个未经检查的强制转换,这也会导致警告。
我建议禁止警告,因为代码将彻底失败,即使值实现Comparable与不合适的类型参数(如果它们实现Comparable,但是无法与同一类的实例进行比较,请正确使用它们... )。
答案 2 :(得分:1)
我会像这样重写这段代码:
if (value instanceof Comparable<?>) { // <-- notice <?>
// Declare local var and cast it here
// You will incur warning, but it's localized to this one instance only
//
// Also not that this cast is safe as it matches the signature of Comparable
// in Java 1.4
@SuppressWarnings( "unchecked" )
Comparable<Object> comp = (Comparable<Object>)value;
// Now you can use compareTo
isMatch = (comp.compareTo(selectedValue) == 0);
} else {
//fallback to equals
isMatch = selectedValue.equals(value);
}
答案 3 :(得分:0)
警告是因为使用Comparable时没有使用泛型类型。
无论是哪个类value
,您都希望让该类实现Comparable<Value>
,其中泛型类型Value
是class
值。
然后,您只需拨打value.compareTo(selectedValue)
即可,无需使用第value instanceof Comparable
行。
答案 4 :(得分:0)
@SuppressWarnings(2 p)在旧的Java 5.0中没有特别好用(没有Java 1.5)但是,由于Java 5.0已经使用了近一年,我建议你使用Java 6并没有更好地抑制警告。
要认识到的重要一点是它只是一个警告。即使是集合库也无法在没有警告的情况下进行编译,并且设计者似乎并不打算总是编写根本不会产生警告的代码。
答案 5 :(得分:0)
您可以通过确保值类扩展可比较来修复警告。
class ClassOfValueUsingCompareTo implements Comparable{
//class definition
}
来源:http://forums.sun.com/thread.jspa?threadID=785803
如果你这样做,你可能不得不通过引入更多的抽象来改变逻辑 1)使用接口提供多态性。 2)将isMatch操作封装在多态类定义的方法中。
public interface ValueInterface{
//interface definition
public boolean isMatch();
}
class ClassOfValueUsingCompareTo implements ValueInterface,Comparable{
//class definition
public boolean isMatch(){
//use compareto
}
}
class ClassOfValueUsingEquals implements ValueInterface{
//class definition
public boolean isMatch(){
//use equals
}
}
作为旁注:使用instanceOf运算符时出现问题 Avoiding instanceof in Java
希望这能回答你的问题。