与通用编译错误 [英] Compilation error with generic

查看:138
本文介绍了与通用编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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, as MyClass and not MyClass<?>), you have opted out of generics entirely, and the return type of getMyTypes() is now the raw type Collection, and not Collection<MyType>. As a result, you can't use the enhanced for syntax with type MyType, you'd have to use Object instead.

Of course, the better solution is just to use MyClass<?> (rather than just MyClass) when you mean a MyClass of an unknown parameterized type.

这篇关于与通用编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆