Может ли "это" когда-либо быть null в Java?


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

public void dataViewActivated(DataViewEvent e) {
    if (this != null)
        // Do some work
}

будет ли эта строка когда-либо оцениваться как false?

10 101

10 ответов:

нет, этого не может. Если вы используете this, то вы находитесь в экземпляре так this не null.

JLS говорит:

при использовании в качестве основного выражения ключевое слово this обозначает значение, которое является ссылкой на объект, для которого был вызван метод экземпляра (§15.12), или на создаваемый объект.

если вы вызвали метод из объекта, то объект существует или у вас будет NullPointerException раньше (или это статика метод, но тогда вы не можете использовать this в нем).


ресурсы :

это все равно что спросить себя: "жив ли я?"this никогда не может быть null

не, ключевое слово "this" само по себе представляет текущий живой экземпляр (объект) этого класса в рамках этого класса, с помощью которого вы можете получить доступ ко всем его полям и членам (включая конструкторы) и видимым из его родительского класса.

и, что более интересно, попробуйте установить это:

this = null;

об этом думаете? Как это может быть возможно, не будет ли это похоже на обрезание ветки, на которой вы сидите. С ключевым словом " это " имеется в таким образом, как только вы говорите this = null; в любом месте класса, то вы в основном просите JVM освободить память, назначенную этому объекту в середине какой-либо операции, которую JVM просто не может позволить произойти, поскольку она должна безопасно вернуться после завершения этой операции.

кроме того, попытка this = null; приведет к ошибке компилятора. Причина очень проста, ключевое слово в Java (или другой язык) не может быть присвоено значение, т. е. ключевое слово не может быть левое значение операции присваивания.

другие примеры, вы не можете сказать:

true = new Boolean(true);
true = false;

Если вы компилируете с -target 1.3 или раньше, то внешнийthis может быть null. Или, по крайней мере раньше...

нет. Чтобы вызвать метод экземпляра класса, экземпляр должен существовать. Экземпляр неявно передается в качестве параметра методу, на который ссылается this. Если this был null тогда не было бы экземпляра для вызова метода.

Это не достаточно, что язык принуждает его. Виртуальная машина должна применять его. Если виртуальная машина не применяет его, вы можете написать компилятор, который не применяет проверку null перед вызовом метода, написанного на Java. Коды операций для вызова метода экземпляра включают загрузку этой ссылки в стек см.:http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787. замена этого на нулевой ref действительно приведет к тому, что тест будет ложь

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

при вызове метода на null ссылки NullPointerException будет выброшен из Java VM. Это по спецификации, поэтому, если ваша виртуальная машина Java строго соответствует спецификации,this не будет null.

нормальный this не может быть null в реальном коде Java1 и ваш пример использует нормальный this. См. другие другие ответы для получения более подробной информации.

квалифицированный thisдолжны никогда null, но можно сломать это. Рассмотрим следующее:

public class Outer {
   public Outer() {}

   public class Inner {
       public Inner() {}

       public String toString() {
           return "outer is " + Outer.this;  // Qualified this!!
       }
   }
}

когда мы хотим создать экземпляр Inner, мы должны сделать это:

public static void main(String[] args) {
    Outer outer = new Outer();
    Inner inner = outer.new Inner();
    System.out.println(inner);

    outer = null;
    inner = outer.new Inner();  // FAIL ... throws an NPE
}

выход:

outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
        at Outer.main(Outer.java:19)

показывает что наша попытка создать Inner С null ссылка на его Outer не удалось.

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

, каждый Inner экземпляр имеет скрытый final синтетическое поле (называется "this"), который содержит ссылку на элемент Outer. Если вы действительно хитрый, можно использовать "не чистый" означает назначить null в поле.
  • вы могли бы использовать Unsafe сделать его.
  • вы можете использовать собственный код (например, JNI), чтобы сделать это.
  • вы можете сделать это с помощью отражения.

в любом случае вы делаете это, конечный результат заключается в том, что Outer.this выражение будет оценено как null2.

короче,можно для квалифицированного this на null. Но это невозможно если ваша программа следует "чистой Java" правила.


1-я сбрасываю со счетов такие трюки, как" написание " байт-кодов вручную и передача их в качестве реальной Java, настройка байт-кодов с помощью BCEL или аналогичного, или переход в собственный код и манипулирование сохраненными регистрами. ИМО, это не Java. Гипотетически, такие вещи могут также произойти в результате ошибки JVM ... но я не помню, чтобы каждый видел сообщения об ошибках.

2 - На самом деле, JLS не говорит, что поведение будет, и это может зависеть от реализации ... среди прочего.

tl; dr, " это " может быть вызвано только из нестатического метода, и все мы знаем, что нестатический метод вызывается из какого-то объекта, который не может быть null.