今天早些时候,我参加了一个名为“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) { ... }
您如何描述这个问题?我只是不知道我的教授想要我回答的问题。
很抱歉,如果报价搞砸了语法。我一直在翻译瑞典语。
答案 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>) { /* ... */ }