将参数化类型实例引用到其原始类型与使用原始类型引用另一个原始类型实例之间的区别?
difference between referencing a parameterized type instance to its raw type and using a raw type to reference another raw type instance?
我最近开始从基础学习 Java 并且我 运行 进入了这个
"little"对泛型类型的误解,提出了如下问题:
将参数化类型实例引用到其原始类型和引用参数化类型实例之间的区别是什么?
使用原始类型引用另一个原始类型实例?
我的意思是,这就是这段代码之间的区别:
ArrayList rawTypeList_NoRawInstance = new ArrayList</*Any type here*/>();
还有这个:
ArrayList rawTypeList_RawInstance = new ArrayList();
代码:
import java.util.*;
public class TestGenerics{
public static void main(String args[]){
ArrayList rawTypeList_RawInstance = new ArrayList();
ArrayList rawTypeList_NoRawInstance = new ArrayList<Integer>(); /* instead of Integer could be placed any kind of type, this
* is just an example */
rawTypeList_RawInstance.add("example RawInstance"); // warning launched
rawTypeList_NoRawInstance.add("example NoRawInstance"); // same warning here
System.out.println(rawTypeList_RawInstance.get(0)); // content showed without errors/warning
System.out.println(rawTypeList_NoRawInstance.get(0)); // same here
String exampleRawInstance1 = (String)rawTypeList_RawInstance.get(0); // raw type instance compiled without error
String exampleNoRawInstance1 = (String)rawTypeList_NoRawInstance.get(0); // Generic type -Integer- instance compiled without error
Integer exampleRawInstance2 = (Integer)rawTypeList_RawInstance.get(0); // ClassCastException as expected
Integer exampleNoRawInstance2 = (Integer)rawTypeList_NoRawInstance.get(0); // same here, logically
}
}
任何人都可以向我解释其中的区别并给我一些可能的不同后果的例子吗?
泛型仅在编译时出现,它们将被编译器删除(这称为类型擦除)。它们用于向编译器提供一些类型信息。这可以帮助您避免类型转换(在 Java 1.5 之前通常如此)并允许编译器进行更多类型检查。对于程序员来说,这也是一个有价值的信息,例如,如果您在接口中看到泛型类型。
没有泛型:
ArrayList list = new ArrayList();
所以,如果你这样写就会有所不同:
ArrayList</*Any type here*/> list = new ArrayList<>();
现在编译器知道 list
.
中的对象类型
但是这个对没有泛型的版本没有真正的区别:
ArrayList list = new ArrayList</*Any type here*/>();
变量列表没有附带泛型信息,所以它和没有泛型的版本一样好(或坏)。
我最近开始从基础学习 Java 并且我 运行 进入了这个 "little"对泛型类型的误解,提出了如下问题:
将参数化类型实例引用到其原始类型和引用参数化类型实例之间的区别是什么? 使用原始类型引用另一个原始类型实例?
我的意思是,这就是这段代码之间的区别:
ArrayList rawTypeList_NoRawInstance = new ArrayList</*Any type here*/>();
还有这个:
ArrayList rawTypeList_RawInstance = new ArrayList();
代码:
import java.util.*;
public class TestGenerics{
public static void main(String args[]){
ArrayList rawTypeList_RawInstance = new ArrayList();
ArrayList rawTypeList_NoRawInstance = new ArrayList<Integer>(); /* instead of Integer could be placed any kind of type, this
* is just an example */
rawTypeList_RawInstance.add("example RawInstance"); // warning launched
rawTypeList_NoRawInstance.add("example NoRawInstance"); // same warning here
System.out.println(rawTypeList_RawInstance.get(0)); // content showed without errors/warning
System.out.println(rawTypeList_NoRawInstance.get(0)); // same here
String exampleRawInstance1 = (String)rawTypeList_RawInstance.get(0); // raw type instance compiled without error
String exampleNoRawInstance1 = (String)rawTypeList_NoRawInstance.get(0); // Generic type -Integer- instance compiled without error
Integer exampleRawInstance2 = (Integer)rawTypeList_RawInstance.get(0); // ClassCastException as expected
Integer exampleNoRawInstance2 = (Integer)rawTypeList_NoRawInstance.get(0); // same here, logically
}
}
任何人都可以向我解释其中的区别并给我一些可能的不同后果的例子吗?
泛型仅在编译时出现,它们将被编译器删除(这称为类型擦除)。它们用于向编译器提供一些类型信息。这可以帮助您避免类型转换(在 Java 1.5 之前通常如此)并允许编译器进行更多类型检查。对于程序员来说,这也是一个有价值的信息,例如,如果您在接口中看到泛型类型。
没有泛型:
ArrayList list = new ArrayList();
所以,如果你这样写就会有所不同:
ArrayList</*Any type here*/> list = new ArrayList<>();
现在编译器知道 list
.
但是这个对没有泛型的版本没有真正的区别:
ArrayList list = new ArrayList</*Any type here*/>();
变量列表没有附带泛型信息,所以它和没有泛型的版本一样好(或坏)。