Java获取数组类型的类

是否有区别,如果有,那么new String[0].getClass()和之间有什么区别String[].class

我对以下事实感兴趣(非详尽清单):

  • 两者都初始化一个空数组吗?

  • 这个空数组是否缓存在 JVM 中?

  • 他们对某个数组类对象进行操作吗?

  • 它们在字节码级别上是否相同?

注意:可能它是以某种方式写在 JLS 中的,但我在任何地方都找不到合适的描述。


RISEBY
浏览 261回答 1
1回答

慕雪6442864

该表达式new String[0].getClass()被直接编译为指令以创建一个新数组,然后调用getClass(). 相比之下,类文字String[].class被编译为单个ldc指令,如“类文字如何编译为 Java 字节码?”中所述。.您可以通过运行以下程序来验证这一点package jvm;import javax.tools.ToolProvider;public class GetArrayClass {&nbsp; &nbsp; public static Class<?> viaGetClass() {&nbsp; &nbsp; &nbsp; &nbsp; return new String[0].getClass();&nbsp; &nbsp; }&nbsp; &nbsp; public static Class<?> viaClassLiteral() {&nbsp; &nbsp; &nbsp; &nbsp; return String[].class;&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; decompile();&nbsp; &nbsp; }&nbsp; &nbsp; private static void decompile() {&nbsp; &nbsp; &nbsp; &nbsp; Object args = new String[]{"-c", GetArrayClass.class.getName()};&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ToolProvider.getSystemJavaCompiler().getClass().getClassLoader()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .loadClass("com.sun.tools.javap.Main")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .getMethod("main", String[].class).invoke(null, args);&nbsp; &nbsp; &nbsp; &nbsp; } catch(ReflectiveOperationException ex) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IllegalStateException(ex);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private GetArrayClass(){}}在 Ideone 上演示public static java.lang.Class<?> viaGetClass();&nbsp; &nbsp; Code:&nbsp; &nbsp; &nbsp; &nbsp;0: iconst_0&nbsp; &nbsp; &nbsp; &nbsp;1: anewarray&nbsp; &nbsp; &nbsp;#1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // class java/lang/String&nbsp; &nbsp; &nbsp; &nbsp;4: invokevirtual #2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Method java/lang/Object.getClass:()Ljava/lang/Class;&nbsp; &nbsp; &nbsp; &nbsp;7: areturnpublic static java.lang.Class<?> viaClassLiteral();&nbsp; &nbsp; Code:&nbsp; &nbsp; &nbsp; &nbsp;0: ldc&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;#3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // class "[Ljava/lang/String;"&nbsp; &nbsp; &nbsp; &nbsp;2: areturn该表达式new String[0]不能被共享数组替换,因为该new运算符保证生成一个具有不同标识的新对象,即new String[0] != new String[0]。但是在这样的用例中,实例是临时的并且没有执行身份敏感操作,JVM 的优化器很有可能会消除分配,以防它成为热点。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java