为了账号安全,请及时绑定邮箱和手机立即绑定

Java获取数组类型的类

Java获取数组类型的类

RISEBY 2021-09-26 16:41:11
是否有区别,如果有,那么new String[0].getClass()和之间有什么区别String[].class?我对以下事实感兴趣(非详尽清单):两者都初始化一个空数组吗?这个空数组是否缓存在 JVM 中?他们对某个数组类对象进行操作吗?它们在字节码级别上是否相同?注意:可能它是以某种方式写在 JLS 中的,但我在任何地方都找不到合适的描述。
查看完整描述

1 回答

?
慕雪6442864

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 的优化器很有可能会消除分配,以防它成为热点。


查看完整回答
反对 回复 2021-09-26
  • 1 回答
  • 0 关注
  • 259 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信