Чи можемо ми прийняти значення масиву за замовчуванням у Java? наприклад, припустимо, що для масиву int встановлено всі нулі?


77

На практиці я можу припустити, що всі масиви int у Java почнуться заповнені нулями? для всіх машин, на яких працює JVM?

Чи це справедливо для всіх типів? шар? логічний? переліки?

Де це офіційно задокументовано?

У підручниках, які я маю, стверджується, що масиви int встановлюються на нуль, але вони також рекомендують писати цикл for, щоб встановити всі значення на нуль просто "щоб бути зрозумілішим".


14
Викиньте ті підручники. У гіршому випадку вони повинні були сказати вам зателефонувати Arrays.fill(myArr, 0). Але це все ще смішна пропозиція, насправді, якщо мова йде про ясність, додайте проклятий коментар, не робіть зайвої роботи.
Mark Peters

6
Мова Java гарантує, що змінні ініціалізуються до значення за замовчуванням (false, 0, null, залежно від типу). Немає необхідності ініціалізувати масив вручну, це просто марно витрата процесорних циклів.
Стів Куо

1
Ці підручники написані програмістами C / C ++, для яких нещодавно виділені масиви мають невизначений вміст. Java намагається уникнути невизначеної поведінки.
Raedwald,

Це те, що відбувається, коли викладачам C / C ++ доручається викладати клас Java на кафедрі без будь-якої додаткової підготовки, автор, можливо, навіть був учнем такого викладача ... і тут ми розглядаємо застарілі припущення.
Jason K.

Відповіді:


138

Специфікація мови Java - правильне місце для пошуку такої інформації:

Компоненти масиву - це безіменні змінні, які створюються та ініціалізуються до значень за замовчуванням (§4.12.5) щоразу, коли створюється новий об’єкт, що є масивом.

Самі значення за замовчуванням наведені в розділі 4.12.5 .

  • Для байту типу значення за замовчуванням дорівнює нулю, тобто значення (байт) 0 .
  • Для типу short значення за замовчуванням дорівнює нулю, тобто значення (short) 0 .
  • Для типу int значення за замовчуванням дорівнює нулю, тобто 0 .
  • Для типу long значення за замовчуванням дорівнює нулю, тобто 0L .
  • Для типу float значенням за замовчуванням є додатний нуль, тобто 0,0f .
  • Для типу double значення за замовчуванням є додатним нулем, тобто 0,0d .
  • Для типу char значенням за замовчуванням є нульовий символ, тобто '\ u0000' .
  • Для булевого типу типовим значенням є false .
  • Для всіх типів посилань значення за замовчуванням дорівнює нулю .

Ви можете поводитися з нульовим символом як з нулем? мудрий розрахунок?
committedandroider

Чудова відповідь. Мені було цікаво з цього приводу.
ktm5124

17

Так. Первісні типи в Java завжди нульово ініціалізовані. Посилання також ініціалізуються нулем.


4
+1 і для запису, ось офіційна специфікація: Початкові значення змінних
casablanca

2
Це правильно для значень і полів масиву, але не для локальних змінних. Компілятор вимагає, щоб ви самі їх ініціалізували.
Matthew Flaschen,

boolean ініціалізується значенням false, а не нулем.
Стів Куо,

7

Це має бути специфікація мови Java §4.12.5 Початкові значення змінних . замість §4.5.5

"Для байта типу значення за замовчуванням дорівнює нулю, тобто значення (байт) 0.
Для типу short значення за замовчуванням дорівнює нулю, тобто значення (коротке) 0.
Для типу int значення за замовчуванням дорівнює нулю, тобто 0.
Для типу long значення за замовчуванням дорівнює нулю, тобто 0L.
Для типу float значення за замовчуванням є додатним нулем, тобто 0,0f.
Для типу double значення за замовчуванням є додатним нулем , тобто 0.0d.
Для типу char значенням за замовчуванням є нульовий символ, тобто '\ u0000'.
Для типу boolean значенням за замовчуванням є false.
Для всіх типів посилань (§4.3) значенням за замовчуванням є нуль."


4

Ваш підручник неправильний! Писати такий код безглуздо, і марно витрачати час на його введення та час роботи комп’ютерів.

Як вже говорили інші, компілятор гарантує, що змінним поза методами (змінні класу / екземпляра) надається значення 0, false або null. Як ви, мабуть, знаєте, компілятор не надає змінних всередині значень методів, а натомість змушує вас надавати їм значення перед їх використанням.

Якщо ви зробите щось «правильно», ви виявите, що приблизно 90% -95% ваших «змінних» ніколи не змінюються після того, як їм надано значення. Однак нові програмісти, як правило, роблять такі речі:

int x = 0;

// some code that never uses x

x = 5;

// more code that only reads x and never modifies it.

це перешкоджає можливості позначати х як "остаточний". Якщо ви можете позначити х як "остаточний", це запобігає випадковій зміні значення, що запобігає помилкам.

Я б написав код так:

final int x;

// some code that never uses x

x = 5;

// more code that only reads x and never modifies it.

Це називається порожнім фіналом (кінцевою змінною, яка не має значення при оголошенні).

Якщо ви пам'ятаєте, що змінні класу / екземпляра ініціалізуються середовищем виконання, тоді, сподіваємось, ви не будете писати код, щоб ініціалізувати їх зі значеннями викидання, і тоді ви можете позначити їх як остаточні.

Моя особиста практика полягає в тому, щоб завжди позначати все як остаточне, поки я не зрозумію, що мені потрібно це змінити, і ніколи не ініціалізувати змінну, поки не дізнаюся фактичне значення, яке я хочу мати. Це робить код швидшим (не помітним, оскільки призначення зазвичай дуже швидке) і безпечнішим, оскільки я рідко випадково змінюю значення, коли цього не слід робити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.