假设,您必须经常调用 T get(int)
操作,它从底层数组返回一个对象。基本上,这可以通过两种方式实现:
class GenericArray<T> {
final T[] underlying;
GenericArray(Class<T> clazz, int length) {
underlying = (T[]) Array.newInstance(clazz, length);
}
T get(int i) { return underlying[i]; }
}
和
class ObjectArray<T> {
final Object[] underlying;
ObjectArray(int length) {
underlying = new Object[length];
}
T get(int i) { return (T) underlying[i]; }
}
第一个是使用反射,所以在创建时会比较慢。第二个是使用引入一些开销的向下转换。由于运行时的通用类型删除,必须有一些隐式转换机制。
那么,就 get(i)
而言,这两者是否相等?
最佳答案
让我们检查字节码:
Compiled from "ObjectArray.java"
class lines.ObjectArray<T> {
final java.lang.Object[] underlying;
lines.ObjectArray(int);
Code:
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: aload_0
5: iload_1
6: anewarray #3 // class java/lang/Object
9: putfield #13 // Field underlying:[Ljava/lang/Object;
12: return
T get(int);
Code:
0: aload_0
1: getfield #13 // Field underlying:[Ljava/lang/Object;
4: iload_1
5: aaload
6: areturn
}
Compiled from "GenericArray.java"
class lines.GenericArray<T> {
final T[] underlying;
lines.GenericArray(java.lang.Class<T>, int);
Code:
0: aload_0
1: invokespecial #13 // Method java/lang/Object."<init>":()V
4: aload_0
5: aload_1
6: iload_2
7: invokestatic #16 // Method java/lang/reflect/Array.newInstance:(Ljava/lang/Class;I)Ljava/lang/Object;
10: checkcast #22 // class "[Ljava/lang/Object;"
13: putfield #23 // Field underlying:[Ljava/lang/Object;
16: return
T get(int);
Code:
0: aload_0
1: getfield #23 // Field underlying:[Ljava/lang/Object;
4: iload_1
5: aaload
6: areturn
}
如您所见,get
的字节码是相同的。
关于java - 效率 : generic array vs object array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49710125/