Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛型的编译错误_Java_Generics - Fatal编程技术网

Java 泛型的编译错误

Java 泛型的编译错误,java,generics,Java,Generics,test1和test2之间的区别在哪里? 为什么test1中存在编译错误 import java.util.ArrayList; import java.util.Collection; class MyType { } class MyClass<T> { private Collection<MyType> myTypes = new ArrayList<MyType>(); private Collection<T> m

test1和test2之间的区别在哪里? 为什么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())  {

          }        
     }

}
import java.util.ArrayList;
导入java.util.Collection;
类MyType{
}
类MyClass{
私有集合myTypes=new ArrayList();
私有集合myTs=newarraylist();
公共集合getMyTypes(){
返回myTypes;
}
公共集合getMyTs(){
返回多年电价;
}
}
公共类TestSimple{
public void test1(){
MyClass MyClass=新的MyClass();
对于(MyType MyType:myClass.getMyTypes()){
}
}
public void test2(){
MyClass MyClass=新的MyClass();
集合myTypes=myClass.getMyTypes();
对于(MyType MyType:myTypes){
}
}
公共无效测试3(){
MyClass MyClass=新的MyClass();
for(Long myType:myClass.getMyTs()){
}        
}
}

test2
中,由于您没有参数化
MyClass
getMyTypes()
将有效地返回
Collection
,这是不可分配给
Collection

的,我已经将您的问题隔离到一个较小的示例中,如下所示

import java.util.*;

public class TestSimple {

    static class MyClass<T> {
        private Collection<String> myTypes = new ArrayList<String>();

        public Collection<String> getMyTypes() {
            return myTypes;
        }
    }

    public void test1() {    
        MyClass myClass = new MyClass();
        for (String myType : myClass.getMyTypes())  {
        }
    }
}
import java.util.*;
公共类TestSimple{
静态类MyClass{
私有集合myTypes=new ArrayList();
公共集合getMyTypes(){
返回myTypes;
}
}
public void test1(){
MyClass MyClass=新的MyClass();
对于(字符串myType:myClass.getMyTypes()){
}
}
}
我的怀疑是,所有类型信息都会被剥离,除非您特别告诉它。因此,我的建议是更改您的声明:

before: MyClass myClass = new MyClass();
after:  MyClass<?> myClass = new MyClass();
before:MyClass MyClass=newmyclass();
之后:MyClass MyClass=新建MyClass();

如果您在一个类上定义了一个泛型约束,然后实例化该类而不提供任何泛型约束(也就是说,您完全取消了
),那么您就进入了一个领域,在这个领域中,一切都不再相同了

根据报告:

只允许使用原始类型作为对遗留代码兼容性的让步。强烈反对在Java编程语言中引入泛型之后编写的代码中使用原始类型Java编程语言的未来版本可能不允许使用原始类型。

根据Angelika Langer的优秀作品

原始类型的方法或构造函数具有在类型擦除后将具有的签名。如果擦除更改了参数类型,则对原始类型的方法或构造函数调用将生成未检查的警告

因此,通过将
MyClass
构造为原始类型(即作为
MyClass
而不是
MyClass
),您选择了完全退出泛型,而
getMyTypes()
的返回类型现在是原始类型
Collection
,而不是
Collection
。因此,您不能将增强的
用于类型为
MyType
语法,而必须使用
对象


当然,更好的解决方案是当您指的是未知参数化类型的
MyClass
时,只使用
MyClass
(而不仅仅是
MyClass
)。如果使用泛型类的原始类型,则会忽略类中的所有泛型信息,即使是与类的类型参数无关的无辜信息

class A<T> implements List<String>

    Set<Integer> var;

这种严厉的待遇是没有必要的;他们可能不认为原始类型应该得到太多的资源,所以他们采取了简单的方法,不加区别地从原始类型中删除所有泛型信息。

为什么要使用
MyClass
在test1和test2中未经参数化?因为我对类型一无所知。Java允许这种用法。但是如果我有“public Collection getMyTypes()”我正在等待MyTypes的集合,您会得到什么编译错误?@StriplingWarrior错误:需要不兼容的类型:MyType已找到:object为什么需要为方法
public Collection getMyTypes()参数化它
将参数化为
MyType
?例如,如果您在
MyType
上删除
,删除
Collection getMyTs()
并删除
void test2()
void test3()
,它编译得很好。@glowcoder是的,但我也有“Collection myTs=new ArrayList();”并且它不能被删除removed@Alex见下面我的答案。即使没有这些,问题仍然存在。+1有趣的是,我还没有意识到关于原始类型。可能应将
List
更改为
ArrayList
或示例中的另一个非接口。此外,它看起来像一个原始类型,以同样的方式实现了一个泛型接口,并保留了该类型的信息。我想知道这个决定背后的区别是什么。要使
A
成为原始类,它必须首先是泛型类。如果
class A扩展了B
A
不是原始的,因为A甚至不是泛型的。
class A implements List

    Set var;