Рубрики
Без рубрики

Почему локальные переменные должны быть инициализированы в Java?

Переменные в Java можно разделить на экземпляры, статические и локальные. В программировании это всегда так… С пометкой java, информатика.

Переменные в Java можно разделить на экземпляры, статические и локальные. В программировании всегда желательно объявлять и инициализировать переменную только непосредственно перед ее использованием. Если значение для инициализации не может быть определено, потребность в переменной должна быть переоценена. Это делается для того, чтобы избежать ненужного использования памяти и улучшить читаемость кода из-за уменьшенной области видимости. В Java из этих 3 переменных только одна должна быть инициализирована перед ее использованием, иначе компилятор выдаст ошибку. Другими словами, локальные переменные не имеют значений по умолчанию. Ниже приведена таблица различных типов и их значений по умолчанию. Здесь ссылочные типы включают в себя оболочки примитивных типов.

байт, короткий, int, длинный 0
поплавок, двойной 0.0
обуглить \u0000
логический ложный
Ссылочный тип нулевой

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

Статические переменные Статические переменные (или переменные класса) – это глобальные переменные, доступные всем программам в запущенном экземпляре JVM. Они объявляются в классах или интерфейсе с ключевым словом static . К ним можно получить доступ с помощью dot . оператор, использующий имя класса/интерфейса. Ниже приведены их особенности,

  • Загружается в память, когда класс загружается еще до того, как объект класса создается
  • Не участвуйте в сборе мусора

Эти переменные можно оставить неинициализированными после объявления, и им присваивается соответствующее значение по умолчанию. Если статическая переменная объявлена final , она не будет принимать значение по умолчанию. Он должен быть инициализирован либо во время объявления, либо может быть инициализирован в специальном блоке в классе с именем Static Initializer . Не окончательная статическая переменная может быть использована/изменена в любом месте.

Переменные экземпляра Java – это объектно-ориентированный язык программирования. Все в java заключено в класс. Класс обладает свойствами и может выполнять действия. Свойства называются переменными экземпляра. Переменная экземпляра уникальна для каждого созданного объекта. К ним можно получить доступ с помощью dot . оператор, использующий имя объекта. Ниже приведены их особенности,

  • Участвуйте в сборе мусора, как только они выйдут за рамки
  • Область действия находится внутри объекта и не может быть доступна за его пределами.
  • Может быть доступен/изменен только внутри нестатического метода

Эти переменные также можно оставить неинициализированными, как и статические переменные, и они автоматически инициализируются значениями по умолчанию. Если переменная экземпляра объявлена final , она должна быть либо инициализирована во время объявления, либо в конструкторе, либо в специальном блоке, называемом Инициализатор экземпляра .

Локальные переменные Локальные переменные – это те, которые объявляются внутри метода. Они должны быть инициализированы некоторым значением, при сбое которого компилятор выдаст ошибку. Область действия локальной переменной находится внутри метода, и доступ к ней за его пределами невозможен. Эти переменные хранятся в стеке и извлекаются после завершения вызова метода. Для ссылочных типов объект, на который он ссылается, находится в куче, тогда как тип – в стеке.

Приведенный ниже пример кода показывает поведение статической, локальной и переменной экземпляра.

public class Variable{

    public static String staticVariable;
    private final int instanceVariable;
    public boolean defaultInstanceVariable;

    // Static Initializer Block
    static {  
        System.out.println("Static Initializer Block");
        staticVariable= "Static Variable Example";
        System.out.printf("staticVariable After Initialization = %s\n",staticVariable);
    }

    // Instance Initializer Block
    { 
        System.out.println("Instance Initializer Block");
        instanceVariable= 1;
        System.out.printf("instanceVariable After Initialization = %d\n",instanceVariable);
    }

    // Constructor Block
    public Variable(){
        System.out.println("Constructor Block");
            System.out.printf("defaultInstanceVariable = %b\n",defaultInstanceVariable);
    }   

    // Static Method
    public static void staticMethod(){
      System.out.println("Static Method");
  }

    // Instance Method
    public void instanceMethod(){
        char localVariable = '!';
        System.out.println("Instance Method");
    System.out.printf("localVariable After Initialization = %c\n",localVariable );
    }
}


//Call 1:
new Variable().instanceMethod();


//Output 1:
/**
Static Initializer Block
staticVariable After Initialization = Static Variable Example
Instance Initializer Block
instanceVariable After Initialization = 1
Constructor Block
Instance Method
localVariable After Initialization = !
**/

//Call 2:
Variable.staticMethod();

//Output 2:
/**
Static Initializer Block
staticVariable After Initialization = Static Variable Example
Static Method
**/

Почему только локальные переменные?

В Java только локальные переменные имеют очень ограниченную область действия (метод) и время жизни. И у них есть предсказуемый маршрут выполнения, который понимает компилятор. Эти переменные не выходят за рамки метода. Компилятор может определить, где объявлена переменная, и может очень эффективно дать указание программисту инициализировать переменную перед ее использованием. Когда переменная используется без инициализации, существует вероятность потенциальной ошибки в программе. Кроме того, инициализация каждой переменной значением по умолчанию негативно сказывается на производительности. На самом деле это помощь компилятора в улучшении программы. Фактический вопрос должен звучать так: почему компилятор не помогает не использовать статическую переменную/экземпляра перед инициализацией ?

Ответ на этот вопрос заключается в сложности или большем количестве способов доступа к этим переменным. Когда дело доходит до метода, путь выполнения очень ясен. Компилятор может очень хорошо проследить маршрут от использования переменной обратно к ее объявлению. Нет никакого уникального потока, который компилятор мог бы идентифицировать для статической переменной/экземпляра, которая должна быть установлена со значением. Инициализация может происходить в совершенно другой программе, и использование может происходить в каком-то другом месте. Поскольку определенного пути нет, а путь к карте не является узкой линией, им предоставляются значения по умолчанию. Значение по умолчанию определенно лучше, чем неопределенное/случайное значение. Если эти переменные не инициализированы, они могут иметь любое значение для них, и это может быть от нерелевантных данных до конфиденциальных данных.

🔥

Оригинал: “https://dev.to/vivekworks/why-local-variables-need-to-be-initialized-in-java-3pgo”