java - 为什么在调用class.NewInstance()时使用InvokeVirtual而不是InvokeSpecial?

标签 java jvm java-bytecode-asm jvm-hotspot

我正在研究以下java程序的反汇编

public class ASMPlayground {
    private String bar;

    public String getBar(){
        return bar;
    }

    public void setBar(String bar) throws IllegalAccessException, InstantiationException {
        String name = String.class.newInstance();
        System.out.println(name);
    }

    public static void main(String[] args) {

    }
}

以下字节码片段引起了我的注意,并且似乎不是最佳的

LDC Ljava/lang/String;.class
INVOKEVIRTUAL java/lang/Class.newInstance ()Ljava/lang/Object;
CHECKCAST java/lang/String

问题:

当要执行的方法依赖于对象引用时,使用InvokeVirtual。鉴于“Class”是最终的并且 newInstance() 仅存在 在“类”中为什么不使用 InvokeSpecial 而不是 InvokeVirtual ?这样不是性能会更好吗?

最佳答案

InvokeSpecial 用于指定调用

superclass, private, and instance initialization method invocations

规范:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokespecial

Class.newInstance 既不是父类(super class)方法调用,也不是私有(private)方法调用,也不是对初始化方法的调用。它也不是动态方法,InvokeDynamic 在这里没有任何作用。这两个指令都不能在这里使用,因为它会与 jvm 发生冲突。在创建 jvm 时,可以允许用“性能更高”的指令替换某些指令,但正如我在 jvm 中看到的那样,它尚未完成。

Wouldn't it be more performant?

JIT 足够聪明,可以理解在这种情况下不需要遍历虚拟方法表,因此它不应该减慢执行速度。实际性能应该通过实际测试进行比较,但我认为没有理由期望存在显着差异。

关于java - 为什么在调用class.NewInstance()时使用InvokeVirtual而不是InvokeSpecial?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42610150/

相关文章:

java - 使用 crawler4j 抓取 https 页面

java - Java无法从服务器读取数据

java - 将 spring boot 从 2.1.0 升级到 2.2.2.RELEASE ,现在启动时出现异常

scala - 是否可以禁用 JVM JIT 循环优化

java - Hadoop - 启动 YARN 服务时 Java 运行时环境内存不足

java - Java固定线程池有最大尺寸参数吗?

java - 检查非空后出现空指针异常

bytecode - 如何覆盖类文件 (asm.ClassWriter.getCommonSuperClass)?

java - 如何使用反射以外的方式填充 JavaBean

java - 查看登录设备