Java 为什么我可以返回列表未指定类型的列表<;T>;返回类型?
给定以下类Java 为什么我可以返回列表未指定类型的列表<;T>;返回类型?,java,generics,Java,Generics,给定以下类 …为什么这样做有效?我的意思是,我本以为会有ClassCastException或其他什么东西!为什么没有 请有人给我指一个清楚的书面解释,说明这里发生了什么 提前感谢。拥有类型为List的变量并不保证您确实拥有一个foo列表。您将只确保当您尝试拉出Foo时(您不是),您的迭代器不是迭代器,并且您不会在任何地方强制转换到Foo。如果让编译器为您执行强制转换,那么它将按预期中断 List<Foo> foos = bar.foos(); int baz = 0;
…为什么这样做有效?我的意思是,我本以为会有ClassCastException或其他什么东西!为什么没有 请有人给我指一个清楚的书面解释,说明这里发生了什么
提前感谢。拥有类型为
List
的变量并不保证您确实拥有一个foo列表。您将只确保当您尝试拉出Foo时(您不是),您的迭代器不是迭代器
,并且您不会在任何地方强制转换到Foo
。如果让编译器为您执行强制转换,那么它将按预期中断
List<Foo> foos = bar.foos();
int baz = 0;
for (Foo foo : foos) {
System.out.println(foo); // ClassCastException
}
listfoos=bar.foos();
int-baz=0;
for(Foo-Foo:foos){
System.out.println(foo);//ClassCastException
}
如果按照如上所示的“正常”路径,编译器将获得一个迭代器,并将每个元素强制转换为Foo
,因此如果列表不是空的,上述代码将失败
您的代码演示了它们有多糟糕,以及人们应该始终避免它们的原因。List l=new ArrayList();
List l = new ArrayList();
List<Integer> ints = l;
列表ints=l;
当您进行赋值时,您将告诉Java将l
的地址放入ints
中,仅此而已。当泛型从代码中删除时,会在运行时发生这种情况
当编译器试图识别与类型相关的可能错误时,编译器在编译时使用泛型。它不会在编译时崩溃,因为他不知道列表中存储了什么值,因为没有指定任何值。当列表包含意外元素时(因为只有在运行时才会有对象),它将在运行时使用ClassCastException
崩溃
我无法理解为什么他们允许这种情况在编译时发生。如果编译器遇到这样的情况,我会预料到编译错误。您将得到警告,而不是错误
当你做作业时,你只需说“我给你一个列表”,不管里面有什么,你只要把它存储起来就行了
作为建议,请始终指定列表的类型。在您的情况下,请列出
。记住这一点,只要你不需要有一个包含许多对象类型的列表,在我的经验中,这是一种罕见的情况。你可以,因为这个原始类型list sketchy=new arrarylist()代码>。您的IDE还应该在Bar#foos
中警告您该返回。
package whoop.deduper;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author deduper
*
*/
public class Bar {
public <T extends Foo> List<T> foos( ) {
List sketchy = new ArrayList();
sketchy.add( BigDecimal.TEN );
return sketchy;
}
}
package whoop.deduper;
import static java.lang.System.out;
/**
* @author deduper
*
*/
public class EffedUp {
/**
* @param args
*/
public static void main( String[ ] args ) {
int effedUp = new FuBar().fuBar( );
out.println(effedUp + " — But it works!");
}
}
List<Foo> foos = bar.foos();
int baz = 0;
for (Foo foo : foos) {
System.out.println(foo); // ClassCastException
}
List l = new ArrayList();
List<Integer> ints = l;