NullPointerException или распечатает содержимое статической переменной

Я натолкнулся на следующий код:

public class TradingSystem {

    private static String category = "electronic trading system";

    public static void main(String[] args) {
        TradingSystem system = null;
        System.out.println(system.category);
}

Результат: электронная торговая система

Я с удивлением обнаружил исключение NullPointerException!

Q1. Почему он не выбрал NullPointerException?

Q2. Или во время компиляции из-за объявления категории, имеющего static, он заменил систему (например, ссылку на объект) на TradingSystem и как таковой, по существу, TradingSystem.category был вызван?

Ответ 1

Java разрешает доступ к переменным класса (т.е. static) с использованием синтаксиса экземпляра. Другими словами, компилятор позволяет писать system.category, но он разрешает его TradingSystem.category, который не зависит от экземпляра, к которому он обращается.

Вот почему вы не получаете NullPointerException. Однако этот синтаксис не читается и запутан. Вот почему вы должны получить предупреждение и предложение использовать TradingSystem.category вместо system.category.

Ответ 2

Ваш код не отличается от следующего кода концептуально.

public class TradingSystem {

    private static String category = "electronic trading system";

    public static void main(String[] args) {
        System.out.println(TradingSystem.category);

    }
}

Даже если вы, похоже, используете ссылку на системный объект, вы фактически используете статическое значение. Java позволяет использовать экземпляры, когда вы используете static, но вы должны предпочесть выше синтаксис, чтобы было ясно, что вы используете статические.

Ответ 3

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

Ответ 4

static называется "КЛАССОМ" не для объекта класса. Итак, здесь

System.out.println(system.category); "система действует как TradingSystem"

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