与通用编译错误 [英] Compilation error with generic
问题描述
test1和test2的区别在哪里?
为什么在test1中编译错误?
import java.util.ArrayList;
而不是
import java.util.Collection;
class MyType {
}
class MyClass< T> {
私人收藏< MyType> myTypes = new ArrayList< MyType>();
私人收藏< T> myTs = new ArrayList< T>();
公共集合< MyType> getMyTypes(){
返回myTypes;
}
public Collection< T> getMyTs(){
返回myTs;
public class TestSimple {
public void test1(){
MyClass myClass = new MyClass(); (MyType myType:myClass.getMyTypes()){
}
}
public void test2(){
MyClass myClass = new MyClass();
集合< MyType> myTypes = myClass.getMyTypes(); (MyType myType:myTypes){
}
}
public void test3(){
MyClass< Long> myClass = new MyClass< Long>(); (Long myType:myClass.getMyTs()){
}
}
}
$
如果你在一个类上定义了一个通用的约束,然后在没有提供任何类的情况下实例化这个类通用约束(即,完全忽略<>
),那么你刚刚进入 原始类型 ,其中没有任何内容了。
根据 Java语言规范:
原始类型的使用仅允许作为遗留代码兼容性的让步。强烈建议在将通用性引入到Java编程语言后编写的代码中使用原始类型。 未来版本的Java编程语言可能会禁止使用原始类型。
根据到Angelika Langer出色的 Java泛型常见问题,
原始类型的方法或构造函数具有类型擦除后的签名。如果擦除操作改变了参数类型,那么对原始类型的方法或构造函数调用会生成一个未经检查的警告。
所以通过构造
MyClass
作为原始类型(也就是MyClass MyClass<>
),您完全选择了泛型,返回类型getMyTypes()
现在是原始类型集合
,而不是集合< MyType>
。因此,对于MyType
类型的语法,您不能使用增强的语法,您必须使用
Object
代替。
当然,更好的解决方案就是使用
MyClass<> ;当您的意思是
(而不仅仅是MyClass
未知参数化类型时,MyClass
) 。Where is the difference between test1 and test2? Why compilation error in test1?
import java.util.ArrayList; import java.util.Collection; class MyType { } class MyClass<T> { private Collection<MyType> myTypes = new ArrayList<MyType>(); private Collection<T> myTs = new ArrayList<T>(); public Collection<MyType> getMyTypes() { return myTypes; } public Collection<T> getMyTs() { return myTs; } } public class TestSimple { public void test1() { MyClass myClass = new MyClass(); for (MyType myType : myClass.getMyTypes()) { } } public void test2() { MyClass myClass = new MyClass(); Collection<MyType> myTypes = myClass.getMyTypes(); for (MyType myType : myTypes) { } } public void test3() { MyClass<Long> myClass = new MyClass<Long>(); for (Long myType : myClass.getMyTs()) { } } }
解决方案If you define a generic constraint on a class, and then instantiate the class without providing any generic constraint (that is, you leave off the
<>
completely), then you've just stepped into the realm of Raw Types, where nothing is the same anymore.According to the Java Language Spec:
The use of raw types is allowed only as a concession to compatibility of legacy code. The use of raw types in code written after the introduction of genericity into the Java programming language is strongly discouraged. It is possible that future versions of the Java programming language will disallow the use of raw types.
According to Angelika Langer's excellent Java Generics FAQ,
Methods or constructors of a raw type have the signature that they would have after type erasure. A method or constructor call to a raw type generates an unchecked warning if the erasure changes the argument types.
So by constructing
MyClass
as a raw type (that is, asMyClass
and notMyClass<?>
), you have opted out of generics entirely, and the return type ofgetMyTypes()
is now the raw typeCollection
, and notCollection<MyType>
. As a result, you can't use the enhancedfor
syntax with typeMyType
, you'd have to useObject
instead.Of course, the better solution is just to use
MyClass<?>
(rather than justMyClass
) when you mean aMyClass
of an unknown parameterized type.这篇关于与通用编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!