Ідея локальних змінних полягає в тому, що вони існують лише в обмеженій області, для якої вони потрібні. Таким чином, має бути мало причин для невизначеності щодо значення або, принаймні, звідки ця величина. Я міг уявити багато помилок, які виникають із наявності значення за замовчуванням для локальних змінних.
Наприклад, розглянемо наступний простий код ... ( Зверніть увагу, для демонстраційних цілей місцевим змінним присвоюється значення за замовчуванням, як зазначено, якщо явно не ініціалізовано )
System.out.println("Enter grade");
int grade = new Scanner(System.in).nextInt(); //I won't bother with exception handling here, to cut down on lines.
char letterGrade; //let us assume the default value for a char is '\0'
if (grade >= 90)
letterGrade = 'A';
else if (grade >= 80)
letterGrade = 'B';
else if (grade >= 70)
letterGrade = 'C';
else if (grade >= 60)
letterGrade = 'D';
else
letterGrade = 'F';
System.out.println("Your grade is " + letterGrade);
Коли все буде сказано і зроблено, якщо припустити, що компілятор призначив значення "\ 0" за замовчуванням для letterGrade , цей код як написаний буде працювати належним чином. Однак що робити, якщо ми забули інше твердження?
Тестовий запуск нашого коду може призвести до наступного
Enter grade
43
Your grade is
Цей результат, хоча і слід було очікувати, безумовно, не був наміром кодера. Дійсно, напевно, у переважній більшості випадків (або, принаймні, значної їх кількості) значення за замовчуванням не було б бажаним значенням, тому в переважній більшості випадків значення за замовчуванням призведе до помилки. Більше сенсу змусити кодер присвоїти початкове значення локальній змінній перед його використанням, оскільки горе налагодження, спричинене забуттям = 1
в for(int i = 1; i < 10; i++)
значно переважає зручність у тому, що не потрібно включати = 0
в for(int i; i < 10; i++)
.
Це правда, що блоки try-catch-нарешті можуть стати трохи безладним (але це насправді не привід-22, як, мабуть, підказує цитата), коли, наприклад, об’єкт кидає перевірений виняток у своєму конструкторі, але для одного Причина чи інша, щось потрібно зробити цьому об’єкту в кінці блоку, нарешті. Прекрасним прикладом цього є робота з ресурсами, які необхідно закрити.
Один із способів вирішити це в минулому може бути таким ...
Scanner s = null; //declared and initialized to null outside the block. This gives us the needed scope, and an initial value.
try {
s = new Scanner(new FileInputStream(new File("filename.txt")));
int someInt = s.nextInt();
} catch (InputMismatchException e) {
System.out.println("Some error message");
} catch (IOException e) {
System.out.println("different error message");
} finally {
if (s != null) //in case exception during initialization prevents assignment of new non-null value to s.
s.close();
}
Однак, що стосується Java 7, цей остаточний блок більше не потрібен, використовуючи «пробні ресурси».
try (Scanner s = new Scanner(new FileInputStream(new File("filename.txt")))) {
...
...
} catch(IOException e) {
System.out.println("different error message");
}
Однак, як випливає з назви, це працює лише з ресурсами.
І хоча попередній приклад трохи примхливий, це, мабуть, більше говорить про те, як пробують нарешті або ці класи реалізовані, ніж це говорить про локальні змінні та як вони реалізовані.
Це правда, що поля ініціалізуються до значення за замовчуванням, але це трохи інакше. Якщо ви скажете, наприклад, int[] arr = new int[10];
щойно ви ініціалізували цей масив, об’єкт існує в пам'яті в заданому місці. Припустимо на мить, що немає типових значень, але натомість початкове значення є будь-яким рядом 1s та 0s, що знаходиться в цьому місці пам'яті в даний момент. Це може призвести до недетермінованої поведінки у ряді випадків.
Припустимо, у нас ...
int[] arr = new int[10];
if(arr[0] == 0)
System.out.println("Same.");
else
System.out.println("Not same.");
Цілком можливо, що вони Same.
можуть відображатися в одному циклі, а Not same.
можуть бути відображені в іншому. Проблема може стати ще більш гострою, як тільки ви почнете говорити про змінні.
String[] s = new String[5];
Відповідно до визначення, кожен елемент s повинен вказувати на рядок (або нульовий). Однак, якщо початкове значення, яке б число серій 0 і 1 не траплялося в цьому місці пам'яті, не тільки не має гарантії, що ви будете отримувати однакові результати кожен раз, але також немає гарантії, що об'єкт s [0] балів до (припускаючи, що це вказує на щось значуще) навіть є Рядок (можливо, це Кролик,: p )! Ця відсутність турботи про тип летить перед обличчям майже всього, що робить Java Java. Отже, хоча значення за замовчуванням для локальних змінних в кращому випадку можна розглядати як необов’язкове, але значення за замовчуванням для змінних, наприклад, ближче до необхідності .