今天早些时候的考试麻烦 - ArrayList方法

时间:2012-03-12 19:09:51

标签: java android list collections arraylist

今天早些时候,我参加了一个名为“Java for Android I”的课程考试,发现这个问题我不知道。也许有些人可以帮我解释一下。

问题:

  

查看此集合 ArrayList p 。一类人是一个   超级学生。 ArrayList实现List-interface   (根据Java-API)。

     

编译器不会允许代码中提到的某些情况。为什么?   描述它们可能会导致 p 不包含Person的实例   或 p 不是 ArrayList 的原因。例如。 p.add(“你好”); 现在   包含一个String实例。

代码:

p = new ArrayList<Object>();

void method ( ArrayList<Student> als) { ... }

void method ( List<Person> lp ) { ... }

void method ( ArrayList<Object> alo) { ... }

您如何描述这个问题?我只是不知道我的教授想要我回答的问题。

很抱歉,如果报价搞砸了语法。我一直在翻译瑞典语。

4 个答案:

答案 0 :(得分:4)

您的教授的问题是关于Java泛型中类型检查的基础知识。假设:

class Person {
}

class Student extends Person {
}

这是一个有效的代码段:

List<Person> list = new ArrayList<Person>();

就是这样:

List<Object> list = new ArrayList<Object>();

这显然无效,因为对象可以是Person实例而不是Student实例:

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

但是这个是我最喜欢的 - 它总是让人们吵架:

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

这是一个无效的代码段。 “什么为什么!”我听你问。嗯,所有Student对象都是Person的实例,所以这样的作业就可以了:

Person person = new Student();

但是,在参数类型方面,Java编译器会尽最大努力保护您。想象一下这段代码:

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

list.add(new Person());

如果编译器没有反对赋值,那么现在可以将Person个对象输入到只托管ArrayList个对象的Student ...

方法调用以完全相同的方式工作。只需从方法签名中剥离参数的类型,并尝试设想对该类型的赋值......

答案 1 :(得分:1)

很难从你所提供的内容中确切地说出来,但似乎教授可能会试图用泛型来测试你对某些微妙之处的理解。

他没有显示参考文献p的声明是一个线索。

如果传递参考p:

,这是合法的
  

方法(ArrayList&lt; \ Object&gt; alo)//因为类型和参数   完全匹配

这些都是非法的:

method(ArrayList<Student> als) //because the method will expect Student and will get Object
method(List<Person>) //same reason.. expects list of Person, and will get Objects

答案 2 :(得分:0)

虽然没有完全理解你的问题

第一种方法和第三种方法是根据Java overLoading规则的重复方法。编译器会说它们是重复的方法。

答案 3 :(得分:0)

或者它可能是关于以下内容 - 我不确定:)

// take some method
void method ( ArrayList<Object> ) { /* ... */ }

// and an Object
ArrayList<Object> p = new ArrayList<Object>();

现在你可以说method(p)它会起作用,因为方法需要ArrayList<Object>。但

ArrayList<Student> q = new ArrayList<Student>();
method ( q );

不起作用。因为ArrayList<Student>不是ArrayList<Object>Studend extends Object。为了允许你必须定义方法:

void method ( ArrayList<? extends Object> ) { /* ... */ }
// or shorter but the same
void method ( ArrayList<?> ) { /* ... */ }

如果你想要一个可以同时使用ArrayList<Person>ArrayList<Student>(以及Person的所有其他子类)的方法,你必须声明它

void method ( ArrayList<? extends Person>) { /* ... */ }