То же самое касается Билла К. Я добавляю:
Компилятор Java может защитить вас от причинения себе вреда, если не установить переменную перед использованием ее в функции.Таким образом, он явно НЕ устанавливает значение по умолчанию, как описывает Билл К.
Но когда дело доходит до переменных класса, компилятору будет очень трудно сделать это за вас.Переменная класса может быть установлена любой функцией в классе.Компилятору будет очень сложно определить все возможные порядки, в которых могут быть вызваны функции.По крайней мере, он должен был бы проанализировать все классы в системе, которые вызывают любую функцию в этом классе.Возможно, ему придется изучить содержимое любых файлов данных или базы данных и каким-то образом предсказать, что будут делать пользователи.В лучшем случае задача была бы чрезвычайно сложной, в худшем - невозможной.Поэтому для переменных класса имеет смысл обеспечить надежное значение по умолчанию.По умолчанию это, по сути, заполнение поля битами нуля, так что вы получаете нуль для ссылок, ноль для целых чисел, ложь для логических значений и т. Д.
Как говорит Билл, вы определенно НЕ должны привыкатьавтоматической инициализации переменных при их объявлении.Инициализируйте переменные только во время объявления, если это действительно имеет смысл в контексте вашей программы.Например, если в 99% случаев вы хотите, чтобы x было 42, но внутри некоторого условия IF вы можете обнаружить, что это особый случай, и x должно быть 666, тогда хорошо, начните с «int x = 42;»и внутри IF переопределить это.Но в более нормальном случае, когда вы вычисляете значение на основе каких-либо условий, не инициализируйте произвольное число.Просто заполните его расчетным значением.Затем, если вы допустите логическую ошибку и не сможете установить значение при некоторой комбинации условий, компилятор может сказать вам, что вы облажались, а не пользователь.
PS Я видел много неработающих программ, которыескажем, что-то вроде:
HashMap myMap=new HashMap();
myMap=getBunchOfData();
Зачем создавать объект для инициализации переменной, когда вы знаете, что быстро собираетесь выбросить этот объект через миллисекунду?Это просто пустая трата времени.
Редактировать
Если взять тривиальный пример, предположим, что вы написали это:
int foo;
if (bar<0)
foo=1;
else if (bar>0)
foo=2;
processSomething(foo);
Это броситошибка во время компиляции, потому что компилятор заметит, что когда bar == 0, вы никогда не устанавливаете foo, но затем пытаетесь использовать его.
Но если вы инициализируете foo фиктивным значением, например
int foo=0;
if (bar<0)
foo=1;
else if (bar>0)
foo=2;
processSomething(foo);
Тогда компилятор увидит, что независимо от значения bar, foo устанавливается на что-то, поэтому он не выдаст ошибку.Если вы действительно хотите, чтобы foo было 0, когда bar равен 0, то это нормально.Но если на самом деле произошло то, что вы подразумевали, что один из тестов был <= или> =, или вы хотели включить еще один финал, когда bar == 0, то вы обманули компилятор, чтобы он не обнаружил вашу ошибку.И, кстати, я думаю, что такая конструкция - плохой стиль кодирования: не только компилятор не может быть уверен в том, что вы хотели, но и будущий программист по обслуживанию.