Java 6:为什么定义泛型两次?

时间:2014-09-26 19:13:57

标签: java

在Java 6中未定义泛型两次时会发生什么“坏事(tm)”?

List<String> foo = new ArrayList();

而不是

List<String> foo = new ArrayList<String>();

因为根据我的经验,两者编译都很好,并且运行良好。

在Java 7中,可以使用菱形运算符来完全避免这种情况。

List<String> foo = new ArrayList<>();

这更符合DRY原则。

3 个答案:

答案 0 :(得分:8)

  

当泛型未定义两次时会发生什么“坏事(tm)”   Java 6?

默认的no-args构造函数可能没什么不好的,就像ArrayList一样,但是如果有一个列表构造函数接受一个泛型参数,例如

class MyList<T> implements List<T>
{
  T firstValue;

  public MyList( T value )
  {
     firstValue = value;
  }
}

Apple apple = new Apple( );

// This compiles fine, and now we have a problem
// Hence the warning
MyList<Orange> foo = new MyList( apple );

// This does not compile
MyList<Orange> foo = new MyList<Apple>( apple );

// Nor this in Java 7
MyList<Orange> foo = new MyList<>( apple );

答案 1 :(得分:6)

DRY原则很重要,但也有一个原则是“不要在你的项目中留下产生警告的代码”#34;。即使你完全了解原因并且知道它完全无害,消除警告也是一个好习惯。

该行

List<String> foo = new ArrayList();

编译但生成编译器警告,除非您使用@SuppressWarnings进行注释。一般来说,把它写成

就不那么麻烦了
List<String> foo = new ArrayList<String>();

与重复生活在一起。或者更好,升级到JDK7或更高版本。

我如何衡量这两个原则的相对重要性取决于具体情况。延伸到代码的不同部分或不同文件的DRY违规很快就会无法忍受,但这里DRY违规仅限于一行。打字时有一些令人讨厌的价值,但有警告似乎是一个更大的麻烦,并设置了一个不好的先例。

答案 2 :(得分:0)

它只是一种语法,在运行程序时,java对集合的泛型类型一无所知。

有关泛型的所有提示/检查都在编译时发生。如果您首先声明您的变量,如

List<String> foo;

然后将其初始化为

foo = new ArrayList();

您将收到警告,因为编译器怀疑您忘记了foo的声明泛型类型。使用显式泛型类型进行初始化可确保编译器记住所有内容。

是的,它过于冗长,这就是为什么它被替换为钻石运营商&lt;&gt;在Java 7.没什么特别的。