我正在阅读有关C++模板和C#泛型的讨论,以及它们与Java类型擦除泛型的不同之处.我读了一条声明说Java仍然在运行时使用转换,例如在处理集合时.如果这是真的,我不知道它!
假设我有以下代码:
ArrayList<SomeClass> list = new ArrayList<SomeClass>();
...
SomeClass object = list.get(0);
Run Code Online (Sandbox Code Playgroud)
我的问题是.这是否有效编译
ArrayList list = new ArrayList();
...
SomeClass object = (SomeClass) list.get(0);
Run Code Online (Sandbox Code Playgroud)
如果是这样,为什么?我认为list是类型ArrayList<SomeClass>保证的事实,在编译时和运行时,只有SomeClass将存储在ArrayList中?或者你可以做不安全的类型转换来转换ArrayList<OtherClass>为ArrayList<SomeClass>?
是否有其他场合在Java泛型中进行运行时类型转换?
最后,如果确实使用了在运行时进行的转换,那么JIT是否可以忽略运行时转换检查?
(请不要回答/评论微观优化是不值得的,先发制人的优化是万恶之源等等.我在其他类似的问题上看到了这些.这些点很好理解,但它们并没有带走尝试点了解如何在引擎盖下实现类型擦除的泛型.)
你的假设是正确的.
始终需要进行类型检查,因为您可以编写以下法律代码:
ArrayList<X> good = new ArrayList<X>();
ArrayList q = x;
ArrayList<Y> evil = (ArrayList<Y>)q; //Doesn't throw due to type erasure
evil.add(new Y()); //this will actually succeed
X boom = good.get(0);
Run Code Online (Sandbox Code Playgroud)
转换为ArrayListto ArrayList<Y>将(总是)给出一个未经检查的强制转换警告,但是(也总是)会在运行时成功.
这是我写的一个简短的程序:
public class Test<T> {
public T contents;
public Test(T item) {
contents = item;
}
public static void main(String[] args) {
Test<String> t = new Test<String>("hello");
System.out.println(t.contents);
}
}
Run Code Online (Sandbox Code Playgroud)
尝试用它编译javac,然后查看字节码javap -verbose.我选择了几条有趣的线条:
public java.lang.Object contents;
Run Code Online (Sandbox Code Playgroud)
这应该在Test构造函数的定义之前出现.在示例代码中,它是T类型,现在它是一个Object.这是擦除.
现在,看一下主要方法:
public static void main(java.lang.String[]);
Code:
Stack=3, Locals=2, Args_size=1
0: new #3; //class Test
3: dup
4: ldc #4; //String hello
6: invokespecial #5; //Method "<init>":(Ljava/lang/Object;)V
9: astore_1
10: getstatic #6; //Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: getfield #2; //Field contents:Ljava/lang/Object;
17: checkcast #7; //class java/lang/String
20: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
23: return
Run Code Online (Sandbox Code Playgroud)
然后我们可以checkcast在第17行看到命令,就在println之前 - 这是Java从Object被删除的泛型类型转换的地方-String
| 归档时间: |
|
| 查看次数: |
1370 次 |
| 最近记录: |