Java允许我从返回类型Object的函数返回一个String,但是它不允许我从返回类型的ArrayList of Objects
函数返回字符串的ArrayList。在第二个函数中,如果java可以在运行时检查s是一个对象。那么为什么它不能检查Strings的ArrayList实际上是一个ObjectList的ArrayList。
答案 0 :(得分:1)
这就是为什么Java有Generics,想象一下这个案例:
public ArrayList<Object> hola(){
return new ArrayList<String>();
}
它甚至不会通过编译器,因为编译器期望一个接受&#34; Objects&#34;不是字符串,也创建了泛型来避免使用强制转换,并帮助程序员在编译时检查集合中的内容是否与其意图保持的类型相同。您可能认为它违反了多态性的观点,但如果您以积极的方式思考它,那么使用Generic Class
帮助很难。
如果你想做类似的事情,你必须这样做:
public <T extends Object> ArrayList<T> take(ArrayList<T> list){
return new ArrayList<T>();
}
这是正确的方法,<T extends Object>
意味着接受一个Object作为Object的子类,所以它接受所有的东西,因为所有的类都是Object的子类。
答案 1 :(得分:0)
正如@arshaji所说,仿制药不是协变的;有关协方差的快速定义,请参阅this Wikipedia link。
这意味着:while:
Object < String
这不是真的:
List<Object> < List<String>
这是因为类型擦除。在运行时,List<Whatever>
变为List
(出于向后兼容性原因):代码中List
元素的类型信息在运行时丢失。
从本质上讲,虽然技术上不准确,但这个Java 5+代码:
for (final String s: listOfStrings)
doSomethingWith(s);
在运行时与此Java 4代码等效:
for (final Object o: listOfStrings)
doSomethingWith((String) o); // note the cast
答案 2 :(得分:0)
为什么不能检查Strings的ArrayList实际上是对象的ArrayList。
这是因为String
IS-AN Object
,ArrayList<String>
IS-NOT ArrayList<Object>
。您无法在Java中执行以下操作:
ArrayList<Object> objs = new ArrayList<String>();
这意味着无法将ArrayList<String>
分配给ArrayList<Object>
。即使在运行时擦除了Arraylist
的类型,也无法在编译时将一种类型的ArrayList
分配给另一种类型。
如果您希望自己的方法返回任意ArrayList
的{{1}},则可以将方法签名更改为:
Object