有没有区别,如果有,那么new String[0].getClass()
和String[].class
有什么区别?
我对诸如(非详尽列表)之类的事实感兴趣:
注意:可能它以某种方式写在JLS中,但我无法在任何地方找到正确的描述。
表达式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
运算符可以保证生成具有不同标识的新对象,即new String[0] != new String[0]
。但是在这样的用例中,实例是临时的并且没有执行身份敏感操作,如果JVM的优化器成为热点,JVM的优化器将消除分配的可能性很高。