在一个类方法中看到这一行,我的第一反应是嘲笑编写它的开发人员..但是,我想我应该确保我是对的。
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
该行是否会评估为假?
答案 0 :(得分:84)
不,不能。如果您使用的是this
,那么您就在实例中,因此this
不为空。
JLS说:
当用作主表达式时,关键字this表示一个值,该值是对调用实例方法的对象(第15.12节)或对正在构造的对象的引用。
如果你从一个对象调用了一个方法,那么该对象就存在了,或者你之前有一个NullPointerException
(或者它是一个静态方法,但是之后,你不能在其中使用this
)。
资源:
答案 1 :(得分:61)
这就像在问自己“我还活着吗?” this
永远不能为空
答案 2 :(得分:9)
从不,关键字“this”本身表示该类范围内该类的当前活动实例(对象),您可以使用该实例访问其所有字段和成员(包括构造函数) )和其父类的可见部分。
更有趣的是,尝试设置它:
this = null;
想一想?怎么可能,就像削减你所坐的分支一样。由于关键字“this”在类的范围内可用,因此只要你说this = null;在类中的任何地方,你基本上都要求JVM在某些操作过程中释放分配给该对象的内存,JVM不允许这样做,因为它需要在完成该操作后安全返回。
此外,尝试this = null;
将导致编译器错误。原因非常简单,Java(或任何语言)中的关键字永远不会被赋值,即关键字永远不能是赋值操作的左值。
其他例子,你不能说:
true = new Boolean(true);
true = false;
答案 3 :(得分:7)
如果使用-target 1.3
或更早版本进行编译,则外部 this
可能为null
。或者至少过去......
答案 4 :(得分:3)
没有。要调用类实例的方法,实例必须存在。该实例隐式作为参数传递给方法,由this
引用。如果this
为null
,那么就没有实例来调用方法。
答案 5 :(得分:3)
在静态类方法中,this
未定义,因为this
与实例而不是类相关联。我相信在静态上下文中尝试使用this
关键字会产生编译器错误。
答案 6 :(得分:3)
语言强制执行它是不够的。 VM需要强制执行它。除非VM强制执行它,否则您可以编写一个在调用Java编写的方法之前不强制执行空检查的编译器。 实例方法调用的操作码包括将此ref加载到堆栈中,请参阅:http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787。将其替换为空引用确实会导致测试为假
答案 7 :(得分:1)
当您在null
引用上调用方法时,将从Java VM抛出NullPointerException
。这是规范性的,因此如果您的Java VM严格遵守规范,this
永远不会是null
。
答案 8 :(得分:1)
普通this
在真正的Java代码 1 中永远不会是null
,并且您的示例使用普通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
的{{1}}引用失败。
事实上,如果你坚持使用纯粹的Java"信封你不能打破这个。
但是,每个Outer
实例都有一个隐藏的Inner
合成字段(称为final
),其中包含对"this$0"
的引用。如果你真的很棘手,可以使用"非纯粹的"意味着将Outer
分配给该字段。
null
来执行此操作。无论哪种方式,最终结果是Unsafe
表达式将评估为Outer.this
2 。
简而言之,合格null
为this
可能。但如果您的程序遵循" Pure Java"那么不可能规则。
1 - 我打折等#34;写"手工操作字节码并将它们作为真正的Java传递出去,使用BCEL或类似方法调整字节码,或者跳转到本机代码并使用保存的寄存器进行处理。 IMO,这不是Java。假设这样的事情也可能由于JVM错误而发生......但我不记得每一个看到错误的报告。
2 - 实际上,JLS没有说出行为是什么,它可能依赖于实现......等等。
答案 9 :(得分:1)
如果该方法是静态的,则没有任何this
。如果该方法是虚方法,则this
不能为null,因为要调用该方法,运行时将需要使用this
指针引用vtable。如果该方法是非虚拟,则可以,this
为空。
C#和C ++允许使用非虚拟方法,但是在Java中,所有非静态方法都是虚拟的,因此this
永远不会为空。
答案 10 :(得分:0)
tl; dr,“this”只能从非静态方法调用,我们都知道从某种不能为null的对象调用非静态方法。