2015-01-07 3 views
4

Недавно я проходил через a page on javarevisited и нашел блок кода, который попросил читателей, чтобы определить, каким будет выход для него ...Как можно получить доступ к статическим переменным из нулевой ссылки?

Хотя я получил выход я не доволен результатом (который вышел БЫТЬ «Привет»), так как я не знаю, как получить доступ к статическому члену из нулевой ссылки. Что происходит в фоновом режиме?

public class StaticDEMO { 

    private static String GREET = "Hello"; 

    public static void main(String[] args) { 
     StaticDEMO demo = null; 
     System.out.println(demo.GREET); 
     // TODO code application logic here 
    } 
} 
+0

Потому что на самом деле эта ссылка не используется. – immibis

+1

'StaticDEMO demo;' компилятор знает, что 'demo' является ссылкой на класс, это может быть нулевой, но это тип' StaticDEMO', который является вашим классом .. это не объект ... .. Так как статические поля определяется во время компиляции, это нормально. –

ответ

12

Это работает, потому что JVM знает, что вы пытаетесь получить доступ к статическому члену определенного класса. Потому что вам нужно было объявить demo как конкретный класс (в данном случае StaticDEMO), он знает, что нужно использовать его для поиска GREET.

Чтобы быть ясным, вы не сталкиваетесь с этим часто (мне действительно нужно было ввести этот код, чтобы проверить его, я не могу сказать, что я когда-либо видел это). В основном, это хорошая практика всегда ссылаться на статические поля по их классу, а не на экземпляр объекта (который может быть нулевым, как мы видим!).

Значение, предпочитают это:

System.out.println(StaticDEMO.GREET); 

EDIT

Я нашел ссылку на это в Java Specification: Глава 15, Раздел 11: Поле доступа выражений.

Пример 15.11.1-2. Приемник Переменного является Ненужной для статического доступа Поля

Следующей программа демонстрирует, что пустая ссылка может использоваться для доступа (статический) переменного класса, не приводя к исключению

[пример не показано здесь для краткости]

+1

Но, смотря на блок кода, вполне вероятно, что он запустит NULLPOINTEREXCEPTION или NULLREFERENCEEXCEPTION во время выполнения. Мой запрос: как это работает? Мы учили, что статические члены являются членами класса и могут быть доступны только по имени класса. Итак, как в этом случае доступ к статическому элементу осуществляется из нулевой ссылочной переменной? :/ –

+3

Поскольку он не использует ссылку вообще, просто тип ссылки. Даже если вы используете объект вместо класса для ссылки на статическое поле, JVM знает тип объекта (CLASS) и использует его под обложками. Спектр специально называет это законным (раздел 15.11.1). – Todd

4

Любой метод, который оформляется как статический в Java, означает, что этот метод является memeber уровня класса. Это означает, что вам не нужен объект для активации статических элементов. Статический метод/переменная поддерживается самим классом, а не каким-либо экземпляром класса. Здесь, в вашем примере, компилятор уже знает, что член является статическим членом, и ему не нужен какой-либо экземпляр для доступа к этому статическому методу.

+0

Я полностью согласен с вами @Yadu, я знаю, что статический метод/переменная поддерживается самим классом, а не каким-либо экземпляром класса, но мой вопрос заключается в том, как он доступен из нулевой ссылки? –

+0

Поскольку JVm знает, что метод, который вы пытаетесь получить, является статическим, он игнорирует экземпляр. Потому что тот же метод/тот же результат будет возвращен, даже если вы попытаетесь получить доступ к статическому методу с разными экземплярами класса. –

2

Статические элементы хранятся с классом, а не с каким-либо конкретным экземпляром. Таким образом, не имеет значения, что экземпляр имеет значение null - член класса по-прежнему доступен.

0

Виртуальная машина Java просто игнорирует null, потому что GREET является полем класса и demo не имеет значение, ссылка для обозначения Class поля.

Static метод не нужно ссылаться на объект, чтобы его можно было назвать даже ссылкой на объект null.

+1

Красиво объяснено :) –

+0

Вы пытались запустить код, который, как вы говорите, java рассматривает исходный код как? – Cthulhu

Смежные вопросы