Почему этот код не вызывает NullPointerException

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

public class One {

    public static void method() {
        System.out.println("in static one");
    }
}

public class Two {

    static One o;

    public static void main(String[] args) {
        o.method(); // expected NPE here, as o is null
    }
}

Я знаю, что статические методы должны быть вызваны с их именем класса, я даже знаю, что IDE даст предупреждение компилятора, когда мы вызываем статические методы с экземпляром. но мы могли бы также вызвать их, создав экземпляр, однако я никогда не создавал экземпляр здесь, o должен получить значение по умолчанию null, поэтому вызов o.method() должен вызывать NPE во время выполнения, но это не так. можете ли вы, ребята, пролить свет на то, как порядок выполнения находится в этом коде.

Ответ 1

Это работает, потому что имеет значение тип времени компиляции поля o. Компилятор будет компилировать o.method() в тот же самый байтовый код как One.method().

В частности, если у вас был класс Two, который расширяет One, и оба объявляют a static void method(), тогда

One x = new Two();
x.method(); // calls One.method(), not Two.method()

Хорошо для обфускации, менее полезно для ремонтопригодности...

Ответ 2

method является статическим, поэтому ему не нужен экземпляр One.

One o = null;
o.method();

То же, что и:

One.method();

Ответ 3

static методы или переменные связаны с самим определением класса, а не с экземпляром класса. Следовательно, ваш method() доступен на o, но в идеале вы должны вызвать его, используя само название класса:

     One.method();//static way of calling static methods

Ответ 4

Потому что вы объявляете static One o; вне функции main. Вы можете попытаться объявить его внутри функции main, его даже не можно скомпилировать...

Или вы можете объявить его как One o = null в main, тогда он будет скомпилирован, но он будет таким же, как One.method()

Ответ 5

Если бы вы открыли код в своей среде разработки (например, Eclipse) вместо того, чтобы обманывать людей, показывая здесь код, который обеспечивает формирование кода для статических методов в курсивом стиле, тогда вы бы увидели, что в запросе checkstyle указано "Не вызывайте статический метод в экземпляре".

Так что это должно быть

One.method()

вместо

o.method()

Тогда понятно, почему он не сбой!