[英]how the type information is retrieved in generics (Erasure) in Java?
by using generics, we detect any possible during compilation. 通过使用泛型,我们可以在编译过程中检测到任何可能的情况。 for example,
例如,
List<String> list = new ArrayList<String>();
//list.add(new Integer(45)); This will cause compilation error.
list.add("car");
list.add("bus");
list.add("bike");
String vehicle = list.get(0); //compiler-generated cast
when we use raw type instead of generics before Java 1.5, it needs explicit casting. 当我们在Java 1.5之前使用原始类型而不是泛型时,它需要显式转换。 for example,
例如,
List list2 = new ArrayList();
list.add("car");
list.add("bus");
list.add("bike");
String vehicle = (String)list.get(0); //explicit casting is necessary
however with generics, type erasure occurs. 但是,对于泛型,会发生类型擦除。 that is the type information is lost in runtime.
即类型信息在运行时丢失。 if, that is so, how does the JVM know what object type it is retrieving during runtime, whether it is a string object or a person object (compiler generated cast above).
如果是这样,那么JVM如何知道运行时正在检索的对象类型,无论是字符串对象还是人员对象(上面生成的编译器)。 but this valid with generics, which is can cause runtime errors.
但这对泛型有效,可能会导致运行时错误。
List<Object> test = new ArrayList<Object>();
test.add("hello");
test.add(new Integer(34));
finally, Joshua Bloch mentions on page 115 (item 23, effective java) that Set<Object>
is parameterized type representing a set that can contain objects of any type, Set<?>
is a wild card type representing a set that can contain only objects of some unknown type and Set
is a raw type, which opts out of the generic type system. 最后,约书亚·布洛赫(Joshua Bloch)在第115页(有效Java,项目23)中提到
Set<Object>
是参数化类型,表示可以包含任何类型的对象的Set<?>
, Set<?>
是通配符类型,表示只能包含任何类型的对象某些未知类型的对象,而Set
是原始类型,它选择退出通用类型系统。
I do understand what he means by the above statement. 我确实理解上述声明的意思。 some clarifications will help
一些澄清会有所帮助
The compiler inserts cast operations when retrieving items from generic methods; 从通用方法中检索项目时,编译器将插入强制转换操作。 this is the only way that the JVM knows to treat the result of
list.get(0)
as a String
. 这是JVM知道将
list.get(0)
的结果视为String
的唯一方法。 This is why heap pollution (inserting the wrong type of object into a generic collection) can result in a ClassCastException
at runtime. 这就是为什么堆污染(将错误类型的对象插入通用集合中)会在运行时导致
ClassCastException
的原因。
Regarding the wildcards: 关于通配符:
Set<Object>
's generic type is exactly Object
. Set<Object>
的通用类型恰好是Object
。 You can insert and retrieve Object
instances from it, but you can't pass a Set<Integer>
to a method expecting a Set<Object>
, since the method might be planning to add a non- Integer
object to the set. Object
实例,但是不能将Set<Integer>
传递给需要Set<Object>
的方法,因为该方法可能打算将非Integer
对象添加到集合中。 Set<?>
has an unspecified generic type. Set<?>
具有未指定的泛型类型。 A method can retrieve anything from it as an Object
(since everything is an Object
) and can call universal methods on it like hashCode
or toString
, but it can't add anything to the set. Object
检索(因为所有内容都是Object
),并且可以像hashCode
或toString
一样在其上调用通用方法,但不能向集合中添加任何内容。 Set
, as you mention, is the raw type and shouldn't be used in new code. Set
是原始类型,不应在新代码中使用。 I am not very sure, but what I understand by type information is lost at runtime is that there is no way at runtime that a collection is of some specific type . 我不太确定,但是我在运行时会丢失类型信息,这是因为在运行时 无法确定某个特定类型的集合 。 If you add a
String
to a collection, it will be a String
only but the collection does not enforce that all elements should be of type String
如果将
String
添加到集合中,则它将仅是String
但是集合不会强制所有元素都应为String
类型
Generics are implemented by Java compiler as a front-end conversion called erasure.
Java编译器将泛型实现为称为“擦除”的前端转换。 Type erasure applies to the use of generics.
类型擦除适用于泛型的使用。 When generics are used, they're converted into compile time checks and run time type casts .
使用泛型时,它们将转换为编译时检查和运行时类型强制转换 。
Due to type erasure mechanism this code: 由于类型擦除机制,此代码:
List<String> a = new ArrayList<String>();
a.add("foo");
String x = a.get(0);
gets compiled into this: 被编译成这样:
List a = new ArrayList();
a.add("foo");
String x = (String) a.get(0);
Notice extra cast inserted into compiled compiled-code after type erasure. 请注意,类型擦除后,额外的强制类型转换会插入到已编译的编译代码中。
PS: @chrylis has already provided good explanation about your 2nd part of question. PS:@chrylis已经为您的第二部分问题提供了很好的解释。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.