带有列表的原始类型< String>给编译错误 [英] Raw Type with List<String> gives compilation error
问题描述
我有以下通用类:
import java.util.ArrayList;
import java.util.List;
公共类GenericRaw< T> {
public List< String> get(){
返回新的ArrayList<>();
}
}
让我们考虑一下它的用法: p>
public class用法{
public void doSomething(){
GenericRaw base = new GenericRaw();
for(String x:base.get()){}
}
}
对于这段代码,Idea并没有给出任何编译错误,但是Java编译器本身并没有这样做:
java:不兼容类型
required:java.lang.String
found:java.lang.Object
可在JDK上重现1.6.0_33以及JDK 1.7.0_17。
有人可以帮我解释这个问题吗?
我的调查结果。
以下变体可以成功编译:
public void doSomething(){
GenericRaw<> base = new GenericRaw();
for(String x:base.get()){}
}
甚至:
public void doSomething(){
GenericRaw base = new GenericRaw();
列表< String> list = base.get();
for(String x:list){}
}
$
当然。它遵循JLS对原始类型的描述,在 4.8节:
为了便于与非通用遗留代码进行交互,可以使用擦除类型(§4.6)的参数化类型(§4.5)或删除数组类型(§10.1)的元素类型是参数化类型。这种类型被称为原始类型。
GenericRaw< T> 的specs / jls / se7 / html / jls-4.html#jls-4.6rel =nofollow>擦除为:
public class GenericRaw {
public List get(){...}
}
$ b
类型擦除还将构造函数或方法的签名(第8.4.2节)映射到没有参数化类型或类型变量的签名。删除构造函数或方法签名s是一个签名,它包含与s相同的名称和s中给出的所有形式参数类型的删除。
类型参数(§8.4.4)和方法的返回类型(§8.4.5),如果构造函数或方法的签名被擦除,它也会被擦除。
I have the following Generic class:
import java.util.ArrayList;
import java.util.List;
public class GenericRaw<T> {
public List<String> get() {
return new ArrayList<>();
}
}
Let us consider the case of its usage:
public class Usage {
public void doSomething() {
GenericRaw base = new GenericRaw();
for (String x : base.get()) { }
}
}
For this code Idea doesn't give any compilation error but Java compiler itself does:
java: incompatible types
required: java.lang.String
found: java.lang.Object
Reproducible on JDK 1.6.0_33 as well as on JDK 1.7.0_17.
Can someone help me with the explanation of this issue?
Results of my investigations.
The following variants can be successfully compiled:
public void doSomething() {
GenericRaw<?> base = new GenericRaw();
for (String x : base.get()) { }
}
or even:
public void doSomething() {
GenericRaw base = new GenericRaw();
List<String> list = base.get();
for (String x : list) { }
}
解决方案
Can someone help me with the explanation of this issue?
Sure. It's following the JLS's description of raw types, in section 4.8:
To facilitate interfacing with non-generic legacy code, it is possible to use as a type the erasure (§4.6) of a parameterized type (§4.5) or the erasure of an array type (§10.1) whose element type is a parameterized type. Such a type is called a raw type.
The erasure of GenericRaw<T>
is:
public class GenericRaw {
public List get() { ... }
}
because:
Type erasure also maps the signature (§8.4.2) of a constructor or method to a signature that has no parameterized types or type variables. The erasure of a constructor or method signature s is a signature consisting of the same name as s and the erasures of all the formal parameter types given in s.
The type parameters of a constructor or method (§8.4.4), and the return type (§8.4.5) of a method, also undergo erasure if the constructor or method's signature is erased.
这篇关于带有列表的原始类型< String>给编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!