最近,我遇到了java中的数组声明类型,

       int[] arr = { 1, 2, 3, 4, 5 };
       int[] arr1 = new int[5];
       arr1[0] = 0;
       arr1[1] = 1; ..etc


 谁能解释这两者之间的区别,例如在内存分配,访问效率或其他方面?

最佳答案

它们是等效的(假设您实际上将第一个中的值更改为0、1、2、3、4。)

实际上,它们甚至可以编译为几乎相同的字节码。 Java字节码没有什么可简化的,因此编译器几乎只是将“内联”版本扩展为“创建并填充”版本。

您可以通过编译一个简短的测试应用程序来查看此内容:

public class Test {
    private static void inline() {
        int[] x = { 0, 1, 2 };
    }

    private static void explicit() {
        int[] x = new int[3];
        x[0] = 0;
        x[1] = 1;
        x[2] = 2;
    }
}


然后使用javap显示字节码:

$ javap -c --private Test

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

private static void inline();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   dup
   4:   iconst_0
   5:   iconst_0
   6:   iastore
   7:   dup
   8:   iconst_1
   9:   iconst_1
   10:  iastore
   11:  dup
   12:  iconst_2
   13:  iconst_2
   14:  iastore
   15:  astore_0
   16:  return

private static void explicit();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   astore_0
   4:   aload_0
   5:   iconst_0
   6:   iconst_0
   7:   iastore
   8:   aload_0
   9:   iconst_1
   10:  iconst_1
   11:  iastore
   12:  aload_0
   13:  iconst_2
   14:  iconst_2
   15:  iastore
   16:  return

}


(与库存的JDK 7一起编译。当然,确切的编译器行为可能有所不同。)

唯一的区别是“内联”版本每次都使用dup访问x,而不是使用aload_0

内存使用情况将是相同的,我希望JITted代码是相同的(因为它应该能够发现aload_0dup在这里做同样的事情)。

07-26 09:23