可能已经提出了这个问题,但我没有找到任何关于此的问题,
问题:我没有得到以下代码的工作。任何人都可以添加一些要点来理解这个
public static void main(String[] args) {
List list=new ArrayList<>();
list.add("String");
listOPt(list);
}
public static void listOPt(List<Integer> intList){
intList.add(343);
System.out.println(intList.toString());
}
输出:[String, 343]
我也没有得到intList打印字符串的方式。
根据我的理解,如果我们在调用listOPt()
之前添加任何对象,它会插入intList
并且在该函数之后intList
只接受Integer
吗?
但它是如何存储在内存中的?
答案 0 :(得分:1)
Generics最近在JDK中实现,因此决定使用Type Erasure。
这大致意味着在编译时检查泛型,但信息在运行时丢失。将List<? extends Object>
投射到List<Integer>
肯定不会删除您添加的String
项。在其他情况下,您可能会遇到编译错误(即如果oList
是List<String>
)。
答案 1 :(得分:0)
在下面一行,
List<? extends Object> oList=new ArrayList<>();
java将创建一个列表,该列表可以使用Object或对象的任何子类。
在方法listOPt(List<Integer> intList)
,您打算使用类型推断,因为您使用了&lt;&gt;运营商在实例化。但是类型推断在实例化时起作用,它创建了一个可以接受Object和subtype的列表。所以在方法listOPt(..)中它可以接受整数。
基本上,您的List对象与List<Object>
一样好。
答案 2 :(得分:0)
Java编译器使用类型擦除进行编译。表示编译代码时,它将在没有添加泛型的情况下进行编译。请参考Java generics - type erasure - when and what happens和oracle Java compiler Type erasure
如果你仍然希望你的列表接受整数,那么请用泛型声明
List list = new ArrayList();
然后你将无法在其中添加String。
答案 3 :(得分:0)
在您的代码中:
List list=new ArrayList<>();
您尚未使用任何类型删除来声明变量list
。所以编译器实际上将它转换为 RAW TYPE 。这实际上意味着现在这个列表变量可以转换为任何类型的列表,就像你已经完成List<Integer>
一样,并且编译器无法检查变量的内容,因为你没有声明任何类型擦除。
因此,早期存储在变量list
中的内容并不重要,编译器只会将list
视为List<Integer>
的实例。现在,当您调用intList.toString()
时,它基本上会调用此toString
对象中包含的所有对象的list
方法,从而获得该输出。
这基本上是您在使用 Raw Type 时遇到的问题。为了不发生这种问题,请始终使用类型擦除。