在Java 6中使用Generics在右侧?

M S*_*ach 3 java generics diamond-operator

我java 6我可以声明arraylist如下

方式1:使用泛型,也就是<Integer> 在右手边

List<Integer> p = new ArrayList<Integer>();
Run Code Online (Sandbox Code Playgroud)

Way2:使用钻石操作员

List<Integer> p = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)

Way3:仅在左侧使用通用

List<Integer> p = new ArrayList(); 
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用方式3作为简要介绍.这些方式之间有什么区别吗?我们应该选择哪一个?为什么?

更新: -我知道在java 7推荐第二种方式,但我的问题是在java 6的上下文中.哪一个更好?

对我来说,方式3也说p是整数的arraylist(同样通过way1传达).所以我发现除了IDE显示警告信息之外没有区别:

ArrayList是原始类型.ArrayList<E>应参数化对泛型类型的引用

sel*_*lig 6

正如已经指出的那样,Way 2在1.6中无效.所以问题是,方式1和方式3之间是否有任何区别.除了可读性之外,没有.

拿这个代码:

import java.util.*;
class G {
  public static void main(String [] args){
    List<Integer> listOne = new ArrayList<Integer>();
    listOne.add(1);
    int one = listOne.get(0);

    List<Integer> listTwo = new ArrayList();
    listTwo.add(1);
    int two = listTwo.get(0);
  }
}
Run Code Online (Sandbox Code Playgroud)

编译它并使用查看字节码 javap -c

  public static void main(java.lang.String[]);
    Code:
    // FOR listOne
       0: new           #2                  // class java/util/ArrayList
       3: dup           
       4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
       7: astore_1      
       8: aload_1       
       9: iconst_1      
      10: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      13: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      18: pop           
      19: aload_1       
      20: iconst_0      
      21: invokeinterface #6,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      26: checkcast     #7                  // class java/lang/Integer
      29: invokevirtual #8                  // Method java/lang/Integer.intValue:()I
      32: istore_2      
   // FOR listTwo
      33: new           #2                  // class java/util/ArrayList
      36: dup           
      37: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
      40: astore_3      
      41: aload_3       
      42: iconst_1      
      43: invokestatic  #4                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      46: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      51: pop           
      52: aload_3       
      53: iconst_0      
      54: invokeinterface #6,  2            // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
      59: checkcast     #7                  // class java/lang/Integer
      62: invokevirtual #8                  // Method java/lang/Integer.intValue:()I
      65: istore        4
      67: return        
}
Run Code Online (Sandbox Code Playgroud)

我们可以看到在两种情况下都产生完全相同的字节码.请注意,由于编译器中的Generics未被烘焙,因此在编译时检查它后会丢弃信息,并添加checkcast指令以确保在检索对象时它所执行的强制转换是安全的.