Java中的“this”可以为空吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3789528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can "this" ever be null in Java?
提问by Bryce Fischer
Saw this line in a class method and my first reaction was to ridicule the developer that wrote it.. But then, I figured I should make sure I was right first.
在一个类方法中看到这一行,我的第一反应是嘲笑编写它的开发人员..但后来,我想我应该首先确保我是对的。
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
Will that line ever evaluate to false?
那条线会评估为假吗?
采纳答案by Colin Hebert
No it can't. If you're using this
, then you're in the instance so this
isn't null.
不,不能。如果您正在使用this
,则您在实例中,因此this
不为空。
The JLS says :
JLS 说:
When used as a primary expression, the keyword this denotes a value that is a reference to the object for which the instance method was invoked (§15.12), or to the object being constructed.
当用作主要表达式时,关键字 this 表示一个值,该值是对调用实例方法的对象(第 15.12 节)或正在构造的对象的引用。
If you invoked a method from an object, then the object exists or you would have a NullPointerException
before (or it's a static method but then, you can't use this
in it).
如果你从一个对象调用了一个方法,那么这个对象就存在,或者你会有一个NullPointerException
before(或者它是一个静态方法,但是你不能this
在它里面使用)。
Resources :
资源 :
回答by bragboy
It's like asking yourself "Am I alive?" this
can never be null
这就像问自己“我还活着吗?” this
永远不能为空
回答by Claudiu
No. To call a method of an instance of a class, the instance has to exist. The instance is implicitly passed as a parameter to the method, referenced by this
. If this
was null
then there'd have been no instance to call a method of.
不可以。要调用类实例的方法,该实例必须存在。该实例作为参数隐式传递给方法,由 引用this
。如果this
是,null
那么就没有调用方法的实例。
回答by burkestar
In static class methods, this
isn't defined since this
is associated with instances and not classes. I believe it would give a compiler error to attempt to use this
keyword in static context.
在静态类方法中,this
没有定义,因为this
它与实例而不是类相关联。我相信尝试this
在静态上下文中使用关键字会导致编译器错误。
回答by Tom Hawtin - tackline
If you compile with -target 1.3
or earlier, then an outerthis
may be null
. Or at least it used to...
如果您使用-target 1.3
或更早版本进行编译,则外部this
可能是null
. 或者至少它曾经...
回答by tia
When you invoke a method on null
reference, the NullPointerException
will be thrown from Java VM. This is by specification so if your Java VM strictly complies to the specification, this
would never be null
.
当您在null
引用上调用方法时,NullPointerException
将从 Java VM 抛出。这是由规范决定的,因此如果您的 Java VM 严格遵守规范,则this
永远不会是null
.
回答by Adam
tl;dr, "this" can only be called from a non-static method and we all know that a non-static method is called from some sort of object which cannot be null.
tl; dr,“this”只能从非静态方法调用,我们都知道非静态方法是从某种不能为空的对象调用的。
回答by Rune FS
It's not enough that the language enforces it. The VM needs to enforce it. Unless the VM enforces it you could write a compiler that does not enforce the null check prior to calling the method written in Java. The opcodes for a instance method invocation include loading the this ref on to the stack see: http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787. Substituting this for a null ref would indeed result in the test being false
语言强制执行它是不够的。VM 需要强制执行它。除非 VM 强制执行它,否则您可以编写一个编译器,该编译器在调用用 Java 编写的方法之前不强制执行空检查。实例方法调用的操作码包括将 this ref 加载到堆栈上,请参见:http: //java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787。将此替换为空引用确实会导致测试为假
回答by sactiw
No never, the keyword 'this' itself represents the current alive instance (object) of that class within the scope of that class, with which you can access all its fields and members (including constructors) and the visible ones of its parent class.
No never,关键字“this”本身表示该类范围内该类的当前活动实例(对象),您可以使用它访问其所有字段和成员(包括构造函数)及其父类的可见字段。
And, more interestingly, try setting it:
而且,更有趣的是,尝试设置它:
this = null;
Think about it? How can it be possible, won't it be like cutting the branch you are sitting on. Since keyword 'this' is available within the scope of the class thus as soon as you say this = null; anywhere within the class then you are basically asking JVM to free the memory assigned to that object in the middle of some operation which JVM just can't allow to happen as it needs to return back safely after finishing that operation.
考虑一下?怎么可能,岂不是砍断你所坐的树枝。由于关键字“this”在类的范围内可用,因此只要您说 this = null; 在类中的任何地方,您基本上都是在要求 JVM 在某些操作中间释放分配给该对象的内存,JVM 不允许发生该操作,因为它需要在完成该操作后安全返回。
Moreover, attempting this = null;
will result in compiler error. Reason is pretty simple, a keyword in Java (or any language) can never be assigned a value i.e. a keyword can never be the left value of a assignment operation.
此外,尝试this = null;
将导致编译器错误。原因很简单,Java(或任何语言)中的关键字永远不能赋值,即关键字永远不能是赋值操作的左值。
Other examples, you can't say:
其他的例子,你不能说:
true = new Boolean(true);
true = false;
回答by Stephen C
A normal this
can never be null
in real Java code1, and your example uses a normal this
. See other the other answers for more details.
法线this
永远不会出现null
在真正的 Java 代码1 中,并且您的示例使用了法线this
. 有关更多详细信息,请参阅其他其他答案。
A qualified this
shouldnever be null
, but is possible to break this. Consider the following:
合格的this
不应该是null
,但有可能打破这一点。考虑以下:
public class Outer {
public Outer() {}
public class Inner {
public Inner() {}
public String toString() {
return "outer is " + Outer.this; // Qualified this!!
}
}
}
When we want to create an instance of Inner
, we need to do 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
}
The output is:
输出是:
outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
at Outer.main(Outer.java:19)
showing that our attempt to create an Inner
with a null
reference to its Outer
has failed.
表明我们尝试创建Inner
一个null
引用它的对象Outer
失败了。
In fact, if you stick within the "Pure Java" envelope you cannot break this.
事实上,如果你坚持“纯Java”信封,你就无法打破这一点。
However, each Inner
instance has a hidden final
synthetic field (called "this$0"
) that contains the reference to the Outer
. If you are really tricky, it is possible to use "non-pure" means to assign null
to the field.
但是,每个Inner
实例都有一个隐藏的final
合成字段(称为"this$0"
),其中包含对 的引用Outer
。如果你真的很棘手,可以使用“非纯”的方式来分配null
给字段。
- You could use
Unsafe
to do it. - You could use native code (e.g. JNI) to do it.
- You could do it by using reflection.
- 你可以
Unsafe
用来做。 - 您可以使用本机代码(例如 JNI)来执行此操作。
- 你可以通过使用反射来做到这一点。
Either way you do it, the end result is that the Outer.this
expression will evaluate to null
2.
无论采用哪种方式,最终结果都是Outer.this
表达式的计算结果为null
2。
In short, it is possiblefor a qualified this
to be null
. But it is impossibleif your program follows the "Pure Java" rules.
总之,这是可能的有资格的this
是null
。但是,如果您的程序遵循“纯 Java”规则,则这是不可能的。
1 - I discount tricks such as "writing" the bytecodes by hand and passing them off as real Java, tweaking bytecodes using BCEL or similar, or hopping into native code and diddling with the saved registers. IMO, that is NOT Java. Hypothetically, such things might also happen as a result of a JVM bug ... but I don't recall every seeing bug reports.
1 - 我不喜欢手工“编写”字节码并将它们作为真正的 Java 传递,使用 BCEL 或类似方法调整字节码,或跳入本机代码并玩弄保存的寄存器等技巧。IMO,那不是 Java。假设,这样的事情也可能是由于 JVM 错误而发生的……但我不记得每次看到错误报告。
2 - Actually, the JLS does not say what the behavior will be, and it could be implementation dependent ... among other things.
2 - 实际上,JLS 并没有说明行为会是什么,它可能取决于实现......等等。