有区别吗?如果是,那么new String[0].getClass()
和String[].class
有什么区别?
我对诸如(非详尽列表)之类的事实感兴趣:
注意:也许它是用JLS编写的,但是我在任何地方都找不到合适的描述。
答案 0 :(得分:3)
表达式new String[0].getClass()
被直接编译为指令以创建新数组,然后调用getClass()
。相反,类文字String[].class
被编译成单个ldc
指令,如“How is a class literal compiled to Java bytecode?”所述。
您可以通过运行以下程序来验证这一点
package jvm;
import javax.tools.ToolProvider;
public class GetArrayClass {
public static Class<?> viaGetClass() {
return new String[0].getClass();
}
public static Class<?> viaClassLiteral() {
return String[].class;
}
public static void main(String[] args) {
decompile();
}
private static void decompile() {
Object args = new String[]{"-c", GetArrayClass.class.getName()};
try {
ToolProvider.getSystemJavaCompiler().getClass().getClassLoader()
.loadClass("com.sun.tools.javap.Main")
.getMethod("main", String[].class).invoke(null, args);
} catch(ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
private GetArrayClass(){}
}
public static java.lang.Class<?> viaGetClass();
Code:
0: iconst_0
1: anewarray #1 // class java/lang/String
4: invokevirtual #2 // Method java/lang/Object.getClass:()Ljava/lang/Class;
7: areturn
public static java.lang.Class<?> viaClassLiteral();
Code:
0: ldc #3 // class "[Ljava/lang/String;"
2: areturn
表达式new String[0]
不能被共享数组替换,因为new
运算符得到了保证,可以产生具有不同标识的新对象,即{{1 }}。但是在这样的用例中,实例是临时的,并且不执行任何对身份敏感的操作,因此,如果它成为热点,JVM的优化器很可能会取消分配。