[英]Using Generics on right hand side in Java 6?
I java 6 i can declare the arraylist as follows 我java 6我可以声明arraylist如下
Way1: using generics ie <Integer>
on right hand side too Way1:在右手边也使用泛型,即<Integer>
List<Integer> p = new ArrayList<Integer>();
Way2: using the diamond operator Way2:使用钻石操作员
List<Integer> p = new ArrayList<>();
Way3: using generic only at left side Way3:仅在左侧使用通用
List<Integer> p = new ArrayList();
I prefer to use way 3 as its brief. 我更喜欢使用方式3作为简要介绍。 Is there any difference between these ways? 这些方式之间有什么区别吗? Which one we should prefer and why? 我们应该选择哪一个?为什么?
Update:- I know in java 7 second way is recommended but my question is in context of java 6. Which one is preferable? 更新: -我知道在java 7推荐第二种方式,但我的问题是在java 6的上下文中。哪一个更好?
To me, way 3 also says p is an arraylist of integers (same conveyed by way1). 对我来说,方式3也说p是整数的arraylist (同样通过way1传达)。 So I find no difference except the fact IDE displays warning message: 所以我发现除了IDE显示警告信息之外没有区别:
ArrayList is a raw type. ArrayList是原始类型。 References to generic type
ArrayList<E>
should be parameterized 应该参数化对泛型类型ArrayList<E>
引用
As has been pointed out, Way 2 isn't valid in 1.6. 正如已经指出的那样,Way 2在1.6中无效。 So the question is, is there any difference between Way 1 and Way 3. Apart from readability, no. 所以问题是,方式1和方式3之间是否有任何区别。除了可读性之外,没有。
Take this code: 拿这个代码:
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);
}
}
Compile it and look at the bytecode using javap -c
编译它并使用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
}
We can see that the exact same bytecode is produced in both cases. 我们可以看到在两种情况下都产生完全相同的字节码。 Note that as Generics aren't baked in the compiler throws away the information after checking it at compile time and adds in checkcast
instructions to make sure the casts it does when retrieving objects are safe. 请注意,由于编译器中的Generics未被烘焙,因此在编译时检查它后会丢弃信息,并添加checkcast
指令以确保在检索对象时它执行的强制转换是安全的。
第二种方式在Java 6中是不可能的。它是在Java 7中推断通用实例的新方法。
没有区别,如果你使用java 7更喜欢第二种方法,但它在java 6中不可用。它是java 7的新增功能 。
两者都相同,但是way2可以从java 7获得
Both are same .But there are version difference in both of this. 两者都是一样的。但是这两者都有版本差异。
But second way is not possible in java 6.In Java 7 if we not declare type in right side then by default it will take same type as left side. 但是第二种方式在java 6中是不可能的。在Java 7中,如果我们不在右侧声明类型,那么默认情况下它将采用与左侧相同的类型。
http://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html http://docs.oracle.com/javase/7/docs/technotes/guides/language/type-inference-generic-instance-creation.html
So as per your updates, if you have to use Java 6,then you should use way1. 因此,根据您的更新,如果您必须使用Java 6,那么您应该使用way1。
Way 3 uses raw types . 方式3使用原始类型 。 You should never use raw types. 你永远不应该使用原始类型。 They should only be used in legacy code. 它们只应在遗留代码中使用。
Way 3 is not good. 方式3并不好。 Mixing Generics and raw types is naughty, as you are making an assumption for runtime about types, and can run into ClassCastExceptions like the following code: 混合泛型和原始类型是顽皮的,因为您正在为运行时关于类型做出假设,并且可以运行ClassCastExceptions,如下面的代码:
ArrayList b = new ArrayList();
b.add(5);
ArrayList<String> a = new ArrayList(b);
System.out.println(a.get(0));
So for Java 6, always use way 1 因此对于Java 6,始终使用方式1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.