1 回答
TA贡献1812条经验 获得超5个赞
该表达式new String[0].getClass()被直接编译为指令以创建一个新数组,然后调用getClass(). 相比之下,类文字String[].class被编译为单个ldc指令,如“类文字如何编译为 Java 字节码?”中所述。.
您可以通过运行以下程序来验证这一点
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(){}
}
在 Ideone 上演示
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 的优化器很有可能会消除分配,以防它成为热点。
添加回答
举报