Может ли "это" когда-либо быть null в Java?
увидел эту строку в методе класса, и моей первой реакцией было высмеять разработчика, который ее написал.. Но потом я решил, что сначала должен убедиться в своей правоте.
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
будет ли эта строка когда-либо оцениваться как false?
10 ответов:
нет, этого не может. Если вы используете
this
, то вы находитесь в экземпляре такthis
не null.JLS говорит:
при использовании в качестве основного выражения ключевое слово this обозначает значение, которое является ссылкой на объект, для которого был вызван метод экземпляра (§15.12), или на создаваемый объект.
если вы вызвали метод из объекта, то объект существует или у вас будет
NullPointerException
раньше (или это статика метод, но тогда вы не можете использоватьthis
в нем).
ресурсы :
не, ключевое слово "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
выражение будет оценено какnull
2.короче,можно для квалифицированного
this
наnull
. Но это невозможно если ваша программа следует "чистой Java" правила.
1-я сбрасываю со счетов такие трюки, как" написание " байт-кодов вручную и передача их в качестве реальной Java, настройка байт-кодов с помощью BCEL или аналогичного, или переход в собственный код и манипулирование сохраненными регистрами. ИМО, это не Java. Гипотетически, такие вещи могут также произойти в результате ошибки JVM ... но я не помню, чтобы каждый видел сообщения об ошибках.
2 - На самом деле, JLS не говорит, что поведение будет, и это может зависеть от реализации ... среди прочего.