ArrayList<Integer> 自动将其类型更改为 ArrayList<String>
ArrayList<Integer> automatically change its type to ArrayList <String>
public void run(){
setFont("Courier-24");
//Define list as ArrayList<Integer>
ArrayList<Integer> list = new ArrayList<Integer>();
readList(list);
}
private void readList(ArrayList list){
list.add("Hello");
list.add(2);
println("list = "+list);
println("Type of list = "+list.get(0).getClass());
println("Type of list = "+list.get(1).getClass());
}
结果:
list = [Hello, 2]
Type of list = class java.lang.String
Type of list = class java.lang.Integer
这是我的代码和结果。我的问题是,Integer 类型的 ArrayList 怎么可能存储 String 对象?现在的列表类型是什么?这是什么机制?
在您的 readList
方法的参数中,您没有将它限制为仅 Integer
值类型,因此 list
无法获得编译时检查的好处,必须诉诸到运行时类型检查。
Java 的泛型实际上并没有改变底层的 class 或对象,它们只是提供(大部分)围绕它们的编译时语义。
通过将 ArrayList<Integer>
传递给需要 ArrayList
的方法(可以容纳 任何东西 ),您将绕过编译器为您提供的能力具有那种类型的安全性。
Java Generics Tutorial explains this, and why Java implements generics this way. This page,特别关注:
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
- Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
- Insert type casts if necessary to preserve type safety.
- Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
没有说明的是,这还允许 使用 泛型编写的代码(如您的 run
)与使用 编写的代码进行交互 泛型(就像你的 readList
),这在向具有庞大库基础的非常成熟的语言添加功能时很重要(就像在向 Java 添加泛型时一样) .
声明
ArrayList list
方法中的readList等同于
ArrayList<Object> list
很明显String是Object,Integer也是。当传递给 println 时,两者都将使用自己的方法进行 toString。
当您声明时:
private void readList(ArrayList list)
您没有为此 ArrayList
指定任何类型,因此默认情况下它是 Object
.
类型
String
和Integer
(实际上java中的所有类)都是Object
的子类型。因此可以将它们添加到列表中。
有关没有类型的泛型的更多信息,请阅读 here。简而言之,泛型类型仅用于编译时检查,因此您不会添加错误的类型(稍后可能会导致异常。在这种情况下,您对 String
和 Integer
的操作是兼容的,幸运的是没有错误)。
我认为没有作为参数传递的泛型规范的 ArrayList 类型被假定为 ArrayList。 String 和 Integer 都继承了 Object,因此它们都可以添加到列表中。但是 ArrayList 元素是对象类型。
public void run(){
setFont("Courier-24");
//Define list as ArrayList<Integer>
ArrayList<Integer> list = new ArrayList<Integer>();
readList(list);
}
private void readList(ArrayList list){
list.add("Hello");
list.add(2);
println("list = "+list);
println("Type of list = "+list.get(0).getClass());
println("Type of list = "+list.get(1).getClass());
}
结果:
list = [Hello, 2]
Type of list = class java.lang.String
Type of list = class java.lang.Integer
这是我的代码和结果。我的问题是,Integer 类型的 ArrayList 怎么可能存储 String 对象?现在的列表类型是什么?这是什么机制?
在您的 readList
方法的参数中,您没有将它限制为仅 Integer
值类型,因此 list
无法获得编译时检查的好处,必须诉诸到运行时类型检查。
Java 的泛型实际上并没有改变底层的 class 或对象,它们只是提供(大部分)围绕它们的编译时语义。
通过将 ArrayList<Integer>
传递给需要 ArrayList
的方法(可以容纳 任何东西 ),您将绕过编译器为您提供的能力具有那种类型的安全性。
Java Generics Tutorial explains this, and why Java implements generics this way. This page,特别关注:
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
- Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.
- Insert type casts if necessary to preserve type safety.
- Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
没有说明的是,这还允许 使用 泛型编写的代码(如您的 run
)与使用 编写的代码进行交互 泛型(就像你的 readList
),这在向具有庞大库基础的非常成熟的语言添加功能时很重要(就像在向 Java 添加泛型时一样) .
声明
ArrayList list
方法中的readList等同于
ArrayList<Object> list
很明显String是Object,Integer也是。当传递给 println 时,两者都将使用自己的方法进行 toString。
当您声明时:
private void readList(ArrayList list)
您没有为此 ArrayList
指定任何类型,因此默认情况下它是 Object
.
String
和Integer
(实际上java中的所有类)都是Object
的子类型。因此可以将它们添加到列表中。
有关没有类型的泛型的更多信息,请阅读 here。简而言之,泛型类型仅用于编译时检查,因此您不会添加错误的类型(稍后可能会导致异常。在这种情况下,您对 String
和 Integer
的操作是兼容的,幸运的是没有错误)。
我认为没有作为参数传递的泛型规范的 ArrayList 类型被假定为 ArrayList。 String 和 Integer 都继承了 Object,因此它们都可以添加到列表中。但是 ArrayList 元素是对象类型。