3

我知道当我使用关键字调用其构造函数时会创建一个array对象:Javanew

int[] myIntArray = new int[3];

但如果我改为写

int[] myIntArray = {1,2,3};

创建了一个array对象,但我没有用new. 这在底层是如何工作的——如何在不调用构造函数的情况下在 Java 中创建对象?

4

6 回答 6

7

就创建数组对象而言,它是语法糖。编译后,它的工作方式与标准语法完全相同。

不过这里的不同之处在于,在第一个版本中,您没有填充数组 - 所有元素都是 的默认值int,即 0。

在第二个版本中,您正在创建填充数组。

于 2013-06-21T22:55:53.040 回答
5

这部分:

{1,2,3}

是一个数组初始值设定项,可用作声明的一部分。引用JLS,第 10.6 节

数组初始值设定项可以在声明中指定(第 8.3 节、第 9.3 节、第 14.4 节),或者作为数组创建表达式的一部分(第 15.10 节)来创建数组并提供一些初始值。

ArrayInitializer: { VariableInitializersopt ,opt }

于 2013-06-21T22:58:38.117 回答
4

第一个版本使用默认值填充整数数组0。第二个明确地分配值。

第一个版本相当于

int[] myIntArray = {0, 0, 0};

而第二个与

int[] myIntArray = new int[] {1,2,3};

new 关键字仅对非声明性语句是强制性的,例如 .

int[] myIntArray;
myIntArray = new int[] {1,2,3};
于 2013-06-21T22:55:37.650 回答
2

两种说法都是一样的。第二条语句 int[] myIntArray = {1,2,3}; 是使用新方法的语法的捷径。

int[] myIntArray ={1,2,3} ,这种情况下数组的长度由大括号之间提供的值的数量决定,并用逗号分隔。

于 2013-06-21T23:10:44.647 回答
2

获取这段代码并编译它:

public class ArrayTest {
    public static void main1() {
        int[] array = new int[3]; array[0] = 10; array[1] = 20; array[3] = 30;
    }

    public static void main2() {
        int[] array = new int[] {10, 20, 30};
    }

    public static void main3() {
        int[] array = {10, 20, 30};
    }
}

然后使用javap -c反汇编查看其字节码,得到如下结果。但是您会看到后面的两个片段或方法编译为相同的字节码。所以int[] array = new int[] {1, 2, 3}int[] array = {1, 2, 3}都是一样的。但是单独创建一个数组并为其每个元素分配值的处理方式不同,因此后面的两个片段不是第一个片段的语法糖。

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

public static void main1();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   astore_0
   4:   aload_0
   5:   iconst_0
   6:   bipush  10
   8:   iastore
   9:   aload_0
   10:  iconst_1
   11:  bipush  20
   13:  iastore
   14:  aload_0
   15:  iconst_3
   16:  bipush  30
   18:  iastore
   19:  return

public static void main2();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   dup
   4:   iconst_0
   5:   bipush  10
   7:   iastore
   8:   dup
   9:   iconst_1
   10:  bipush  20
   12:  iastore
   13:  dup
   14:  iconst_2
   15:  bipush  30
   17:  iastore
   18:  astore_0
   19:  return

public static void main3();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   dup
   4:   iconst_0
   5:   bipush  10
   7:   iastore
   8:   dup
   9:   iconst_1
   10:  bipush  20
   12:  iastore
   13:  dup
   14:  iconst_2
   15:  bipush  30
   17:  iastore
   18:  astore_0
   19:  return
于 2013-06-21T23:18:26.390 回答
0

在底层,两种初始化数组的方法是相同的。

再举一个例子,看看这个:

String str = "Hello"; // no 'new' statement here

String str = new String("Hello");

两种语句都做同样的事情,但一种比另一种方便得多。但在引擎盖下,它们在编译后几乎做同样的事情。

于 2013-06-21T23:02:02.940 回答