Полагаться на инициализацию поля по умолчанию - это плохой стиль программирования?

Мне дали ссылку на официальную документацию оракула: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

где сказано:

Значения по умолчанию

Не всегда необходимо присваивать значение, когда поле объявлено. Поля, которые объявлены, но не инициализированы, будут установить разумное значение по умолчанию компилятором. Вообще говоря, по умолчанию это будет ноль или ноль, в зависимости от типа данных. Полагаясь на таких значениях по умолчанию, однако, как правило, считается плохим стиль программирования.

Я хочу подчеркнуть эту часть:

Однако использование таких значений по умолчанию считается плохим стилем программирования.

Но, о боже, это, я бы сказал, фундаментальная часть спецификации языка, зная, что переменные экземпляра имеют значения по умолчанию. С какой стати это плохая практика программирования, если она широко используется даже в исходном коде библиотек Java SE?

Ответ 1

Просто: полагаться на значения по умолчанию не означает намерения.

Вы действительно хотели, чтобы это поле начиналось с 0, или вы забыли присвоить значение?!

И, конечно же, нулевая ссылка - это половина из двух вещей, которые необходимо выполнить для исключения из нулевого указателя.

Наконец, использование значений по умолчанию подразумевает, что у вас есть не окончательные поля. Чего вы избегаете, где это возможно.

Единственный встречный аргумент: зачем записывать то, что вам не нужно? Но я думаю, что перечисленные недостатки заключаются в том, что, таким образом, явно присваивать 0 полю лучше, чем оставлять его компилятору.

Ответ 2

  С какой стати это плохая практика программирования

Идея состоит в том, что если вы полагаетесь на значение по умолчанию, то никому не сразу понятно, кто читает код, если вы намеренно оставили его как значение по умолчанию или просто забыли назначить его.

... если он широко используется даже в исходных кодах библиотек Java SE??

Исходный код Java на самом деле не является чем-то, на что вы должны полагаться в качестве примера примерной практики кодирования. Есть много случаев, когда такие правила нарушаются (иногда намеренно для незначительного улучшения производительности, а иногда случайно или потому, что принятый стиль изменился за эти годы).

Ответ 3

Цитируемый текст:

"Однако полагаться на такие значения по умолчанию считается плохим стилем программирования".

Цинично: "обычно считается, что" часто является способом сказать, что автор не пытался найти авторитетный источник для представляемого утверждения.

В этом случае утверждение явно сомнительно. Доказательства: 5 из 5 выбранных руководств по стилю Java НЕ говорят о том, следует ли вам полагаться на значения по умолчанию:

(Note, my methodology for sampling was to look at the first 5 distinct Google search hits for "java style guide". Then I searched each document for "default". This is not a thorough analysis, but it serves to make my point.)


ХОРОШО. Так действительно ли это способствует удобочитаемости кода Java?

Это спорно.

С одной стороны, начинающий Java-программист, который не узнал об инициализации по умолчанию, может быть сбит с толку тем, откуда берутся нули или нули. Но если они пытаются найти явную инициализацию и обнаруживают, что ее нет, этого должно быть достаточно, чтобы они прочитали учебник или книгу, чтобы узнать об инициализации по умолчанию. (Вы бы надеялись!)

С другой стороны, мы обычно не ожидаем, что начинающие Java-программисты будут поддерживать производственные базы кода. Для опытного Java-программиста избыточная инициализация не улучшает читабельность. Это (в лучшем случае) шум.

На мой взгляд, единственная вещь, которая достигается избыточной инициализацией поля, - это сообщить будущему читателю вашего кода, что вы подумали о начальном значении. (Как выразился @GhostCat, инициализация по умолчанию не передает намерения.)

Но, с другой стороны, если бы я был таким читателем, я бы не обязательно доверял размышлениям автора кода. Так что ценность этого "сигнала" также сомнительна.


Как насчет надежности?

В Java это не имеет значения. JLS указывает, что инициализация по умолчанию происходит для полей. И наоборот, для локальных переменных это ошибка компиляции, чтобы попытаться использовать переменную, которая не была определенно инициализирована.

Короче говоря, поведение переменной, которая не инициализирована явно, полностью предсказуемо.

В отличие от таких языков, как C или C++, где переменные не могут быть инициализированы, поведение не определено и может привести к сбоям и различиям в поведении на разных платформах. Случай всегда явной инициализации переменных здесь гораздо сильнее.


Как насчет производительности?

Это не должно иметь никакого значения. JIT-компилятор должен обрабатывать избыточную инициализацию и инициализацию по умолчанию как одно и то же.

Ответ 4

Для сравнения:

1) Здесь инициализация по умолчанию не используется, потому что переменная установлена в конструкторе:

public class Human {
    private int age;

    public Human(int age){
        this.age = age;
    }
}

2) Здесь оно используется, потому что мы хотим показать, что это значение является преднамеренным

public class Counter {
    private int cnt = 0;

    public void addOne(){
        cnt++;
    }
}