Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中创建泛型类实例的正确方法是什么?_Java_Generics - Fatal编程技术网

在Java中创建泛型类实例的正确方法是什么?

在Java中创建泛型类实例的正确方法是什么?,java,generics,Java,Generics,在Java中初始化泛型类的实例时,在语句的两侧指定类型有什么好处吗 或者换一种说法,这两种说法的区别是什么: ArrayList<String> test = new ArrayList<String>(); ArrayList test=new ArrayList(); 以及: ArrayList test=new ArrayList(); (第二种说法似乎并不等同于: ArrayList<String> test = new ArrayList<

在Java中初始化泛型类的实例时,在语句的两侧指定类型有什么好处吗

或者换一种说法,这两种说法的区别是什么:

ArrayList<String> test = new ArrayList<String>();
ArrayList test=new ArrayList();
以及:

ArrayList test=new ArrayList();
(第二种说法似乎并不等同于:

ArrayList<String> test = new ArrayList<Object>();
ArrayList test=new ArrayList();

第三条语句无效,并导致
不兼容类型
编译错误。)

第二条语句与第一条语句大致相同,但这只是因为泛型在运行时被擦除。您将得到一个“未经检查的转换”警告,这就是我不喜欢它的原因

更好的方法是使用如下静态泛型方法:

public static <T> List<T> newList() {
    return new ArrayList<T>();
}
List<Double> doubleList = Lists.newLinkedList();
下面是生成的字节码(由
javap-c GenericDeclarationTest
打印):

从“GenericDeclarationTest.java”编译而来
类GenericDeclarationTest扩展了java.lang.Object{
GenericDeclarationTest();
代码:
0:aload_0
1:invokespecial#1;//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:new#2;//类java/util/ArrayList
3:dup
4:invokespecial#3;//方法java/util/ArrayList。”“:()V
7:astore_1
8:aload_1
9:ldc#4;//字符串
11:invokeinterface#5,2;//接口方法java/util/List.add:(Ljava/lang/Object;)Z
16:流行音乐
17:aload_1
18:iconst_0
19:invokeinterface#6,2;//InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
24:checkcast#7;//类java/lang/String
27:astore_2
28:new#2;//类java/util/ArrayList
31:dup
32:invokespecial#3;//方法java/util/ArrayList。“”:()V
35:astore_3
36:aload_3
37:ldc#4;//字符串
39:invokeinterface#5,2;//接口方法java/util/List.add:(Ljava/lang/Object;)Z
44:流行音乐
45:aload_3
46:iconst_0
47:invokeinterface#6,2;//接口方法java/util/List.get:(I)Ljava/lang/Object;
52:checkcast#7;//类java/lang/String
55:astore 4
57:返回
}
正如你所看到的(如果你有耐心的话),两者是相同的

顺便说一句,这在Java7中可能会变得更容易。“为泛型实例创建改进的类型推断”中有一个。如果它进行最终剪切,语法将为:

List<String> test = new ArrayList<>();
// or
Map<String, Object> test2 = new HashMap<>();
List test=newarraylist();
//或
Map test2=新的HashMap();

键入不是很难,是吗?

第二条语句或多或少与第一条语句等效,但这只是因为泛型在运行时被擦除。您将得到一个“未经检查的转换”警告,这就是我不喜欢它的原因

更好的方法是使用如下静态泛型方法:

public static <T> List<T> newList() {
    return new ArrayList<T>();
}
List<Double> doubleList = Lists.newLinkedList();
下面是生成的字节码(由
javap-c GenericDeclarationTest
打印):

从“GenericDeclarationTest.java”编译而来
类GenericDeclarationTest扩展了java.lang.Object{
GenericDeclarationTest();
代码:
0:aload_0
1:invokespecial#1;//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:new#2;//类java/util/ArrayList
3:dup
4:invokespecial#3;//方法java/util/ArrayList。”“:()V
7:astore_1
8:aload_1
9:ldc#4;//字符串
11:invokeinterface#5,2;//接口方法java/util/List.add:(Ljava/lang/Object;)Z
16:流行音乐
17:aload_1
18:iconst_0
19:invokeinterface#6,2;//InterfaceMethod java/util/List.get:(I)Ljava/lang/Object;
24:checkcast#7;//类java/lang/String
27:astore_2
28:new#2;//类java/util/ArrayList
31:dup
32:invokespecial#3;//方法java/util/ArrayList。“”:()V
35:astore_3
36:aload_3
37:ldc#4;//字符串
39:invokeinterface#5,2;//接口方法java/util/List.add:(Ljava/lang/Object;)Z
44:流行音乐
45:aload_3
46:iconst_0
47:invokeinterface#6,2;//接口方法java/util/List.get:(I)Ljava/lang/Object;
52:checkcast#7;//类java/lang/String
55:astore 4
57:返回
}
正如你所看到的(如果你有耐心的话),两者是相同的

顺便说一句,这在Java7中可能会变得更容易。“为泛型实例创建改进的类型推断”中有一个。如果它进行最终剪切,语法将为:

List<String> test = new ArrayList<>();
// or
Map<String, Object> test2 = new HashMap<>();
List test=newarraylist();
//或
Map test2=新的HashMap();

打字不太难,是吗?

冗余很烦人。您可能希望了解一些工厂方法,这些工厂方法创建的
List
s如下所示:

public static <T> List<T> newList() {
    return new ArrayList<T>();
}
List<Double> doubleList = Lists.newLinkedList();
List doubleList=Lists.newLinkedList();

还要注意。

冗余是令人讨厌的。您可能希望了解一些工厂方法,这些工厂方法创建的
List
s如下所示:

public static <T> List<T> newList() {
    return new ArrayList<T>();
}
List<Double> doubleList = Lists.newLinkedList();
List doubleList=Lists.newLinkedList();

还要注意。

代码中“static”后面的是故意的吗?它的目的是什么?@euphoria83:目的是让编译器知道它是一个泛型方法。请参见第7页及以下内容。与之有何区别:列表x=new ArrayList();你的中间功能呢?当你说第一个和第二个例子或多或少是等价的,区别是什么?一旦代码被编译,这几乎是一样的,但是你无论如何都应该使用第一个方法,否则javac会给你警告。中间函数将检测您正在查找列表并返回一个列表。这样,您只需指定一次。改进的类型推断的主要好处不是减少键入次数,也不是两次键入相同的内容(从而减少犯错误的机会)。代码中的“static”后面是故意的吗?它的目的是什么?@euphoria83:目的是让编译器知道它是一种通用方法