Java 1.4到Java 1.5 - 重写代码并避免@SuppressWarnings

时间:2010-08-04 19:31:24

标签: java generics refactoring

我有一个用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之外别无选择?

6 个答案:

答案 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>,其中泛型类型Valueclass值。 然后,您只需拨打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

希望这能回答你的问题。