Java泛型 - 允许混合类型? [英] Java generics - mixing types allowed?
问题描述
我之前正在运行一些测试,并且找不到解释为什么这段代码会执行它的功能:
public class Test {
public static void main(String [] args){
List< Integer> list = new ArrayList(Arrays.asList(Double.valueOf(0.1234)));
System.out.println(list.get(0)); //打印0.1234
Object d = list.get(0);
System.out.println(d.getClass()); //打印类java.lang.Double
System.out.println(list.get(0).getClass()); // ClassCastException
}
}
这提出了几个问题: p>
- 为什么List< Integer>首先接受Double(应该编译)?
- 为什么第二个印刷工作而不是第三个印刷工作,虽然看起来他们正在做同样的事情?
编辑
我了解以下两条语句:
List aList = new ArrayList(); //我可以在其中添加任何对象
List< Integer> aList = new ArrayList< Integer>(); //我只能添加一些在那里扩展Integer的东西
但我不明白为什么这个是被授权的,为什么它在运行时会在某种程度上起作用,尽管一些操作产生了一个ClassCastException异常 - 我期望在上面发布的代码的第一行发现一个ClassCastException异常:
列表与LT;整数> aList = new ArrayList(); //我可以在那里有任何对象
...新的ArrayList<整数>(...
代替它会导致编译器异常。
为什么它有效:
System.out.println(list.get(0)); //打印0.1234
$ b 方法 Object.toString()
在 Double中是一样的
和整数
(并且因为 System.out.println()
期望一个Object不会被转换为 Integer
(编译器优化了抛出))
Object d = list .get(0);
System.out.println(d.getClass()); //打印类java.lang.Double
System.out.println(list.get(0).getClass()); // ClassCastException
这实际上是从列表中创建一个整数
并且失败。它执行的演员,因为优化器认为它需要做到这一点,因为它并不明显,它不需要。
如果您要将最后一行更改为:
System.out.println(((Object)list.get(0))。getClass());
它的工作原理:)
I was running some tests earlier and could not find an explanation as to why this code does what it does:
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList(Arrays.asList(Double.valueOf(0.1234)));
System.out.println(list.get(0)); //prints 0.1234
Object d = list.get(0);
System.out.println(d.getClass()); // prints class java.lang.Double
System.out.println(list.get(0).getClass()); // ClassCastException
}
}
That raises a few questions:
- why does the List<Integer> accept a Double in the first place (should it compile at all)?
- why does the second print work and not the third, although it looks like they are doing the same thing?
EDIT
I understand the following 2 statements:
List aList = new ArrayList(); //I can add any objects in there
List<Integer> aList = new ArrayList<Integer>(); //I can only add something that extends Integer in there
But I don't understand why this one is authorised and why it actually works to some extent at runtime although some operations produce a ClassCastException - I would have expected a ClassCastException at the first line of the code posted above:
List<Integer> aList = new ArrayList(); //I can any objects in there
If you write
... new ArrayList<Integer>(...
instead it will cause a compiler exception.
On why it works:
System.out.println(list.get(0)); //prints 0.1234
The method Object.toString()
is the same in Double
and Integer
(And because System.out.println()
expects an Object this is not cast into an Integer
(the compiler optimized the cast away))
Object d = list.get(0);
System.out.println(d.getClass()); // prints class java.lang.Double
Same goes for .getClass()
. Here the optimizer again dropped the cast.
System.out.println(list.get(0).getClass()); // ClassCastException
This actually creates an Integer
from the list and that fails. It does the cast because the optimizer thought it need to do it, because its not obvious that it doesn't need to.
If you would change that last line to:
System.out.println(((Object)list.get(0)).getClass());
it works :)
这篇关于Java泛型 - 允许混合类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!