Может ли "this" когда-либо быть пустым в Java?

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

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

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

Ответ 1

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

JLS говорит:

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

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


Ресурсы:

Ответ 2

Ему нравится спрашивать себя: "Я жив?" this никогда не может быть null

Ответ 3

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

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

this = null;

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

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

Обычный this никогда не может быть null в реальном Java-коде 1 и ваш пример использует обычный 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 [email protected]
Exception in thread "main" java.lang.NullPointerException
        at Outer.main(Outer.java:19)

показывающий, что наша попытка создать ссылку Inner с ссылкой null на ее Outer не удалась.

На самом деле, если вы входите в конверт "Чистая Java", вы не можете это сломать.

Однако каждый экземпляр Inner имеет скрытое синтетическое поле final (называемое "this$0"), которое содержит ссылку на Outer. Если вы действительно сложны, можно использовать "нечистые" средства для назначения null в поле.

  • Вы можете использовать Unsafe для этого.
  • Для этого вы можете использовать собственный код (например, JNI).
  • Вы можете сделать это, используя отражение.

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

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


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

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

Ответ 10

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

С# и C++ допускают не виртуальные методы, но в Java все нестатические методы являются виртуальными, поэтому this никогда не будет нулевым.

Ответ 11

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