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;