Як створюється об'єкт масиву, коли використовується список з дужками

Я розумію, що об'єкт array у Java створюється, коли я закликаю його конструктор з ключовим словом new :

int[] myIntArray = new int[3];

Але якщо я замість цього пишу

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

створюється об'єкт array , але я не називаю його конструктором за допомогою new . Як це працює під капотом - як об'єкт може бути створений в Java без виклику конструктора?

3

6 Відповіді

Що стосується створення об'єкта масиву, це синтаксичний цукор. При складанні він працює точно так само, як стандартний синтаксис.

Різниця в цьому полягає в тому, що з першою версією ви не заповнюєте масив - всі елементи є значенням за замовчуванням для int , що дорівнює нулю.

За допомогою другої версії ви створюєте, та заповнюючи масив.

6
додано

Ця частина:

{1,2,3}

це ініціалізатор масивів , який може використовуватися як частина декларації. Щоб навести посилання на JLS, розділ 10.6 :

Ініціалізатор масиву може бути вказаний у декларації (§8.3, §9.3,   §14.4) або як частину виразу створення масиву (§15.10), щоб створити   масив і надайте деякі початкові значення.

     

ArrayInitializer:       {VariableInitializersopt, opt}

5
додано

Перша версія заповнює цілий масив з значенням 0 за замовчуванням. Другий присвоює значення явним чином.

Перша версія еквівалентна

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

а друга - така ж, як і

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

Нове ключове слово є обов'язковим лише для не декларативних тверджень, наприклад.

int[] myIntArray;
myIntArray = new int[] {1,2,3};
4
додано

Візьміть цей код і складіть його:

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."":()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
2
додано

Обидва твердження однакові. Друге твердження int [] myIntArray = {1,2,3}; це скорочення до синтаксису за допомогою нового методу.

int [] myIntArray = {1,2,3}, ця довжина справи масиву визначається кількістю значень, наданих між дужками і розділених комами.

2
додано

Під капотом обидва способи ініціалізації масиву однакові.

Для іншого прикладу, подивіться на це:

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

String str = new String("Hello");

Обидва твердження роблять те ж саме, але це набагато зручніше, ніж інші. Але під капотом, вони дуже багато чого роблять те ж саме після збірки.

0
додано
@ вийя, приємно знайти!
додано Автор jh314, джерело
Я не впевнений, що обидва роблять те ж саме. другий фрагмент коду призведе до виклику конструктора. першого не буде. Ось їх представлення байт-кодів після складання їхніх фрагментів: gist.github.com/VijayKrishna/5834992
додано Автор vijay, джерело
спасибі @ jh314 я радий, що ти так думаєш. Я дивлюся ще, як JIT може скласти його, ось чому я сказав, що я не впевнений. :)
додано Автор vijay, джерело
@PierreRymiortz просто запустіть цю команду у своєму терміналі/командному рядку: javap -c <�ім'я файлу класу без розширення .class>
додано Автор vijay, джерело
-1, тому що перший приклад є прикладом літерального рядка, який інтернований і, можливо, може навіть не створювати об'єкт, тоді як другий приклад - це явна конструкція з літеральним рядком і може створити два об'єкти! (один інтернує, інший - не).
додано Автор Tim Bender, джерело
Прочитайте .class файл із IDE, як eclipse. Існує також інструмент у стандартному jdk, javap , я думаю, це той, але я його не використовував.
додано Автор Tim Bender, джерело
@ Vijay настільки цікаво. Якщо ви не заперечуєте, що я запитую, як отримати доступ до представлення байт-коду після складання.
додано Автор Pierre Rymiortz, джерело
ІТ КПІ - Java
ІТ КПІ - Java
436 учасників