Почему вызов метода (статического) для пустой ссылки не вызывает исключения NullPointerException? - PullRequest
48 голосов
/ 20 июля 2010

Я написал эту программу на Java

public class Why {

  public static void test() {
    System.out.println("Passed");
  }

  public static void main(String[] args) {
    Why NULL = null;
    NULL.test();
  }

}

Я прочитал, что вызов метода для null объекта вызывает NullPointerException, и все же вышеприведенная программа - нет? Почему это? Я что-то не правильно понимаю?

Ответы [ 5 ]

78 голосов
/ 20 июля 2010

test() - это метод static. static член относится к типу и не требует экземпляра для доступа.

Элемент static должен ONLY доступен через выражение типа. То есть вы должны были написать это следующим образом:

Why.test(); // always invoke static method on the type it belongs to!

Java позволяет вам получить доступ к static члену через выражение ссылки на объект, но ОЧЕНЬ вводит в заблуждение, поскольку НЕ - фактическая семантика static доступа к элементу.

Why aNull = null; 
aNull.test(); // DO NOT EVER DO THIS!
// invokes Why.test(), does NOT throw NullPointerException

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

  • Неважно, является ли ссылка на самом деле null, поскольку экземпляр не требуется
  • Если ссылка не null, не имеет значения, какой тип объекта во время выполнения, динамическая отправка отсутствует !!!

Как видите, точные противоположности верны в обеих точках, например, для доступа к элементу. Вот почему static члены должны НИКОГДА не быть доступными "не-1037 *" способом, потому что это дает очень вводящее в заблуждение представление о том, что он фактически делает.

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

3 голосов
/ 20 июля 2010

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

Вы можете сделать что-то вроде (Why) (null) .test (), для получения класса используется только (Why) (null).

3 голосов
/ 20 июля 2010

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

3 голосов
/ 20 июля 2010

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

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

1 голос
/ 17 октября 2013

Статические переменные и методы связаны с классом, а не с любым объектом. Каждый экземпляр класса разделяет переменную класса, которая находится в одном фиксированном месте в памяти.

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

...