开发者社区> 问答> 正文

Java虚拟机进行的数组处理

我对你们所有人都有一个愚蠢的问题。给出以下Java代码

public void funct(String a) {
    byte[] bytearr;

    bytearr = new byte[a.getBytes().length];
    bytearr = a.getBytes();
}

新通话是否有任何改变?特别是,代码的处理方式与

public void funct(String a) {
    byte[] bytearr;

    bytearr = a.getBytes();
}

我问是因为,当执行时,两者都呈现出相同的结果,如果

  • 它们是不同的(在第一种情况下,空间是分配和填充的,而在第二种情况下,它更像是“指针分配”)。
  • 他们是一样的,我想得太多了。
  • 第二个是错误的,但是JVM比我聪明,并且可以修复它。 更一般而言,任何观察JVM背后的内存分配/魔术行为的建议将不胜感激。

谢谢!

问题来源:Stack Overflow

展开
收起
montos 2020-03-25 20:38:12 474 0
1 条回答
写回答
取消 提交回答
  • 它们是不同的,让我们看一下字节码:

    1.版本:

       L0
        LINENUMBER 9 L0
        ALOAD 0
        ICONST_0
        AALOAD
        INVOKEVIRTUAL java/lang/String.getBytes ()[B
        ARRAYLENGTH
        NEWARRAY T_BYTE
        ASTORE 1
       L1
        LINENUMBER 10 L1
        ALOAD 0
        ICONST_0
        AALOAD
        INVOKEVIRTUAL java/lang/String.getBytes ()[B
        ASTORE 1
       L2
        LINENUMBER 11 L2
        RETURN
       L3
        LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
        LOCALVARIABLE bytearr [B L1 L3 1
        MAXSTACK = 2
        MAXLOCALS = 2
    

    2.版本:

       L0
        LINENUMBER 9 L0
        ALOAD 0
        ICONST_0
        AALOAD
        INVOKEVIRTUAL java/lang/String.getBytes ()[B
        ASTORE 1
       L1
        LINENUMBER 10 L1
        RETURN
       L2
        LOCALVARIABLE args [Ljava/lang/String; L0 L2 0
        LOCALVARIABLE bytearr [B L1 L2 1
        MAXSTACK = 2
        MAXLOCALS = 2
    

    区别在于,这些指令来自额外的行:

    LINENUMBER 9 L0
    ALOAD 0
    ICONST_0
    AALOAD
    INVOKEVIRTUAL java/lang/String.getBytes ()[B
    ARRAYLENGTH
    NEWARRAY T_BYTE
    ASTORE 1
    

    这引入了额外的开销(getBytes被调用两次,更多指令)。通过调用bytearr = a.getBytes()jvm,已经可以处理要存储的数组的大小。

    但是由于第一次初始化是多余的,因此编译器可能会在某个时候(经过足够的运行)对其进行优化。仍然不需要额外的指令和可读性较低的代码。

    回答来源:Stack Overflow

    2020-03-28 09:38:40
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
The Reactive Cloud Native Arch 立即下载
JAVA开发手册1.5.0 立即下载