【问题标题】:what is the difference between two ways of array declaration and initialization in javajava中数组声明和初始化的两种方式有什么区别
【发布时间】:2018-04-21 08:50:24
【问题描述】:

我们可以通过两种方式之一声明和初始化一维数组

一个我们可以使用 new 关键字声明,而在另一个我们不使用 new 关键字。那么当我们不使用 new 关键字时,内存分配是如何完成的。 另外,在 java 中使用数组时,我们什么时候应该进行新的声明

int []a = new int[5];
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
a[4]=5;

int []b = {1,2,3,4,5}

【问题讨论】:

  • 你写它的方式实际上是唯一的区别。这两个初始化在语义上是相同的。备注:在Java中,数组括号应该直接在类型之后,而不是在变量名之前,因为它们会影响类型:int []b -> int[] b
  • @Turing85:谢谢你的解释,所以这意味着使用第二种声明和初始化方式也可以像 new 关键字一样工作。在幕后它会像完成一样分配内存用新的关键字。它只是语义上的差异。
  • "这只是语义上的差异。" - 如果“语义”是指“句法”,那么是的 =)
  • @Turing85:是的,再次感谢您的澄清!

标签: java arrays


【解决方案1】:

正如 cmets 中已经提到的:实践中没有区别。所以区别主要是句法


这可能比您所要求的要多一些细节,但是:它不是完全句法的。有趣的是,字节码略有不同。考虑这个类:

class ArrayInit
{
    public static void main(String args[])
    {
        initA();
        initB();
    }


    public static void initA()
    {
        int []a = new int[5];
        a[0]=1;
        a[1]=2;
        a[2]=3;
        a[3]=4;
        a[4]=5;
    }

    public static void initB()
    {
        int[] b = {1,2,3,4,5};
    }
}

编译并反汇编生成的class文件

javap -c ArrayInit

打印两种方法的结果字节码。此处显示了两种方法的字节码的并排比较:

public static void initA();     public static void initB(); 
  Code:                              Code:
     0: iconst_5                        0: iconst_5
     1: newarray       int              1: newarray       int
     3: astore_0                         
     4: aload_0                         3: dup
     5: iconst_0                        4: iconst_0
     6: iconst_1                        5: iconst_1
     7: iastore                         6: iastore
     8: aload_0                         7: dup
     9: iconst_1                        8: iconst_1
    10: iconst_2                        9: iconst_2
    11: iastore                        10: iastore
    12: aload_0                        11: dup
    13: iconst_2                       12: iconst_2
    14: iconst_3                       13: iconst_3
    15: iastore                        14: iastore
    16: aload_0                        15: dup
    17: iconst_3                       16: iconst_3
    18: iconst_4                       17: iconst_4
    19: iastore                        18: iastore
    20: aload_0                        19: dup
    21: iconst_4                       20: iconst_4
    22: iconst_5                       21: iconst_5
    23: iastore                        22: iastore
                                       23: astore_0
    24: return                         24: return

可以看到,基本上,在第一个变体中,它使用new 并单独分配数组元素,使用aload_0 instructions 将对数组的引用拉入堆栈。在直接初始化中,引用已经在堆栈上,只是与dup instructions 重复。

但是,差异可以忽略不计,最终根本无关紧要:稍微扩展程序以使方法被调用数千次,并使用 java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 检查生成的机器代码表明这两种方法的机器代码实际上最终会相同

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 2021-09-28
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    相关资源
    最近更新 更多