Java arraylist与多态性

Java arraylist与多态性,java,arraylist,polymorphism,return-type,Java,Arraylist,Polymorphism,Return Type,最近我发现了一些关于java的问题。 1. 【A】 [B] ArrayList<Date> dates = new ArrayList<Date>(); dates.add(new Date()); dates.add(new String()); 如果我用这个(下面)怎么办 ArrayList日期=新建ArrayList(); 添加(新日期()); 日期=日期。获取(0); 如果学生是该人的子类型,那么哪些是合法的 Person p = new Student()

最近我发现了一些关于java的问题。 1. 【A】

[B]

ArrayList<Date> dates = new ArrayList<Date>();
dates.add(new Date());
dates.add(new String());
如果我用这个(下面)怎么办

ArrayList日期=新建ArrayList();
添加(新日期());
日期=日期。获取(0);
  • 如果学生是该人的子类型,那么哪些是合法的

    Person p = new Student();
    Student s = new Person();
    List<Person> lp = new ArrayList<Student>();
    List<Student> ls = new ArrayList<Person>();
    
    Person p=新学生();
    学生s=新人();
    List lp=new ArrayList();
    List ls=新的ArrayList();
    

  • 我被这些问题困扰了两天,所以我真的需要有人给我一些解释。提前感谢

    默认情况下,您可以将任何对象放入列表,但从Java 5开始,Java泛型可以限制您可以插入列表的对象类型。以下是一个例子:

    List<MyObject> list = new ArrayList<MyObject>();
    
    以下内容来自oracle的网站

    简而言之,泛型使类型(类和接口)在定义类、接口和方法时成为参数。与方法声明中使用的更为常见的形式参数非常相似,类型参数为您提供了一种方法,可以对不同的输入重复使用相同的代码。区别在于形式参数的输入是值,而类型参数的输入是类型

    与非泛型代码相比,使用泛型的代码有许多好处:

    编译时更强的类型检查。 Java编译器对泛型代码应用强类型检查,并在代码违反类型安全性时发出错误。修复编译时错误比修复运行时错误更容易,因为运行时错误可能很难找到

    消除铸型。 以下不带泛型的代码段需要强制转换:

    List list = new ArrayList();
    list.add("hello");
    String s = (String) list.get(0);
    
    当重新编写以使用泛型时,代码不需要强制转换:

    List<String> list = new ArrayList<String>();
    list.add("hello");
    String s = list.get(0); 
    
    List List=new ArrayList();
    添加(“你好”);
    字符串s=list.get(0);
    
    //无演员阵容 使程序员能够实现通用算法。
    通过使用泛型,程序员可以实现适用于不同类型集合、可定制、类型安全且易于阅读的泛型算法。

    对于问题1和问题2,您需要了解的关键是泛型

    如果你写信

    ArrayList dates = new ArrayList();
    
    ArrayList<Date> dates = new ArrayList<Date>();
    
    然后你会得到一个原始类型:编译器不知道你可以在
    ArrayList
    中放入什么类型的东西。但是当你写作的时候

    ArrayList dates = new ArrayList();
    
    ArrayList<Date> dates = new ArrayList<Date>();
    
    不会编译,因为编译器知道您试图将错误类型的内容放入列表中。同样,你也可以写

    Date date = dates.get(0);
    
    因为编译器知道里面会有一个
    日期
    。对于您的第一个表单,情况并非如此:编译器无法强制执行任何类型检查,因此您需要在导出它时强制转换它:

    Date date = (Date) dates.get(0);
    
    使用原始类型可能会导致程序出错,在程序中您意外地输入了错误的类型,编译器将无法阻止您;而且,当你检索东西时,它也会变得不必要的冗长,因为你必须自己做演员。可以将泛型类型参数(部分代码)看作是一种强制执行列表中的内容的方法。(从技术上讲,这只由编译器强制执行,而不是由运行时强制执行,但这是另一天的教训……如果您感兴趣,请查找类型擦除。)

    对于此代码:

    Person p = new Student();
    Student s = new Person();
    List<Person> lp = new ArrayList<Student>();
    List<Student> ls = new ArrayList<Person>();
    
    上面这条线可以。
    学生
    ,因此
    引用可以保存
    学生
    实例

    Student s = new Person();
    
    不过,你不能做上面这一行。参考
    s
    必须包含对
    学生的参考
    ;而且
    不一定是
    学生
    。这将给您一个编译时错误

    List<Person> lp = new ArrayList<Student>();
    

    这在任何情况下都不起作用,原因与第二行失败的原因相同:一个
    人不一定是
    学生
    ,而且
    列表
    不能包含任何非
    学生

    的内容,尽管无法执行
    列表lp=new ArrayList()
    在某些情况下,您仍然可以使用多态性:
    Person p = new Student();
    Student s = new Person();
    List<Person> lp = new ArrayList<Student>();
    List<Student> ls = new ArrayList<Person>();
    
    Person p = new Student();
    
    Student s = new Person();
    
    List<Person> lp = new ArrayList<Student>();
    
    List<Student> ls = new ArrayList<Person>();