Java 泛型的编译错误
test1和test2之间的区别在哪里? 为什么test1中存在编译错误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
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;