117

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?

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
Bryce Fischer
  • 5,336
  • 9
  • 30
  • 36

11 Answers11

94

No it can't. If you're using this, then you're in the instance so this isn't null.

The JLS says :

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.

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).


Resources :

Colin Hebert
  • 91,525
  • 15
  • 160
  • 151
  • Using it can, however, fail to compile. If it compiles then it's safe to use. – Mark Peters Sep 24 '10 at 17:31
  • Is it just nonsense to do such a check or is it actually prevented by the java language that such a thing can happen? I.e is the null pointer exception thrown before entering the method or only when a member is tried to be accessed? In comparable situations in other languages (in particular C++), this case is undefined behavior and the language will not actively prevent such a scenario. – Johannes Schaub - litb Sep 24 '10 at 17:31
  • 5
    I don't know deeply about Java, but in C++ the `this` of an instance method could be NULL. So I am not quite convinced this is a sufficient reason in Java. – kennytm Sep 24 '10 at 17:32
  • 2
    @Mark Peters: What usages could fail to compile? Use in a static class is the only thing I can think of right now. – FrustratedWithFormsDesigner Sep 24 '10 at 17:32
  • @Johannes: `this` will only compile when it is used in the context of an instance. If somebody tries to call an instance method without giving an instance, it won't compile for *them*, or they'll get an NPE when trying to invoke it on an object. Runtime behaviour is basically irrelevant here unless you do some crazy bytecode manipulation. – Mark Peters Sep 24 '10 at 17:33
  • 1
    @Frustrated: In a static method or static initializer, yes. Or the RHS of a static assignment+declaration. – Mark Peters Sep 24 '10 at 17:34
  • 5
    the null pointer exception in something like `foo.bar()` would be thrown when `foo` is discovered to be `null`. it does happen before entering the method, but the real story is that there is no method to attempt to call. – Claudiu Sep 24 '10 at 17:34
  • 5
    @KennyTM: it is sufficient in Java. If you're using the `this` keyword and it compiles, it's not null when you observe it. But as others say that doesn't prevent an NPE when trying to invoke the method, e.g. But that's completely out of your control as a method and a null check within the method isn't going to change anything. – Mark Peters Sep 24 '10 at 17:37
  • 5
    @Kenny: Not without [undefined behavior](http://stackoverflow.com/q/1844005/54262), though if you know your implementation's details, you could use it. –  Sep 24 '10 at 21:29
  • First time I've seen an incorrect answer with that many upvotes. It is indeed possible to create bytecode that will result in test being false – Rune FS Jul 29 '11 at 12:47
  • 3
    @Rune FS Then, is it still java ? (As a language) – Colin Hebert Jul 29 '11 at 14:16
  • 1
    @Colin what language the code _calling_ the above method is written in doesn't really affect what code the above code is written in does it? – Rune FS Jul 29 '11 at 16:14
  • 1
    *"It is indeed possible to create bytecode that will result in test being false"*. However, unless those bytecodes can also be generated by *JLS conformant* Java compiler, AND loaded / run by a JVM (with the verifier enabled), then you are not talking about a genuine Java method. – Stephen C May 15 '16 at 05:26
  • 5
    I wouldn't subscribe to this definitive answer, even if it makes complete sense. I have crash reports for an Android app where this == null when an instance method is called right after the variable is being null-ified from another thread. The actual call goes through even if the variable is null, and it crashes when it tries to read an instance member :) – Adrian Crețu Sep 06 '16 at 15:08
64

It's like asking yourself "Am I alive?" this can never be null

NullUserException
  • 83,810
  • 28
  • 209
  • 234
bragboy
  • 34,892
  • 30
  • 114
  • 171
  • 47
    _am_ I alive?! o god i don't know anymore – Claudiu Sep 24 '10 at 17:33
  • 1
    You're making it sound like `this != null` was self-evident. It isn't - in C++, for example, `this` may well be `NULL`, for a non-virtual method. – Niki Sep 24 '10 at 19:09
  • 2
    @nikie In some sense, it's self-evident. Even in C++, any program where this happens has undefined behavior. It can also happen for virtual functions on GCC: http://ideone.com/W7RmU . – Johannes Schaub - litb Sep 24 '10 at 19:48
  • @JohannesSchaub-litb It's not true that the behaviour of a c++ program with a null ref for this is undefined. It's defined as long as you do not dereference this – Rune FS Feb 10 '13 at 07:11
9

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.

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.

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.

Other examples, you can't say:

true = new Boolean(true);
true = false;
user3071284
  • 6,955
  • 6
  • 43
  • 57
sactiw
  • 21,935
  • 4
  • 41
  • 28
  • I found this because I wanted to see if I could use `this = null`. My instance was in android where I wanted to remove a view and set the object handling the view to null. Then I wanted to use a method `remove()` which would remove the actual view and then the handler-object would be rendered useless, so I wanted to null it. – Yokich Jul 03 '15 at 07:17
  • Not sure I agree with your claims. (at least the middle part; the lvalue part is fine ... though I'm pretty sure there are in fact broken languages which allow you to assign e.g. true = false (and even languages I wouldn't call broken may allow it with Reflection or similar trickery)). Anyways, If i have some object foo and I were to do (ignoring that it's illegal) foo.this = null, foo would still point to the memory and so the JVM wouldn't garbage collect it. – Foon Dec 04 '15 at 15:31
  • 1
    @Foon well the question precisely talks about Java language, moreover, I haven't came across any language where setting this=null is allowed. That is, if there do exists such languages then I highly doubt that 'this' in such languages will have same context and ideology. – sactiw Dec 07 '15 at 16:06
7

If you compile with -target 1.3 or earlier, then an outer this may be null. Or at least it used to...

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • 2
    I guess through reflection we can set the outer this to null. could be an April fool joke on someone when he got null pointer exception in referencing `Outer.this.member` – irreputable Sep 24 '10 at 21:01
  • 1
    @irreputable might be of interest in deserialization to choose order of outer/inner object instantiation – Sam Ginrich Aug 28 '21 at 18:59
  • @SamGinrich Oh that's an interesting point that no other answer appears to address. In Java Serialization, at least, the order fields are initialised during deserialisation is determined by the stream. OTOH, if that is causing a problem you have bigger issues. – Tom Hawtin - tackline Aug 29 '21 at 20:37
  • @irreputable Actual came here with the order problem, when replacing standard ObjectInpput/OutputStream, which has hard dimension limits. Turned out, reflection can create an inner object "standalone" with Outer.this == null, transiently, and bind the Outer object later (certainly the behaviour is undefined if you do not!) – Sam Ginrich Aug 30 '21 at 20:52
4

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.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
3

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.

A qualified this should never be null, but is possible to break this. Consider the following:

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:

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.

In fact, if you stick within the "Pure Java" envelope you cannot break this.

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.

  • 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.

Either way you do it, the end result is that the Outer.this expression will evaluate to null2.

In short, it is possible for a qualified this to be null. But it is impossible if your program follows the "Pure Java" rules.


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.

2 - Actually, the JLS does not say what the behavior will be, and it could be implementation dependent ... among other things.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

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.

Sai Kishore
  • 326
  • 1
  • 7
  • 16
burkestar
  • 753
  • 1
  • 4
  • 12
3

If the method is static, then there isn't any this. If the method is virtual, then this cannot be null, because in order to call the method, the run-time will need to reference the vtable using the this pointer. If the method is not virtual then, yes, it is possible that this is null.

C# and C++ allow non-virtual methods, but in Java all non-static methods are virtual, so this will never be null.

John Henckel
  • 10,274
  • 3
  • 79
  • 79
  • "in Java all non-static methods are virtual, so `this` will never be `null`" That's what "convinced" me the most. Since methods are by default overridable, the JVM must have a way to know which precise subclass we're calling a method on: this requires having a non-null object pointer. If all classes were concrete or their methods final, it would be possible to rely solely on static dispatch and have a null `this` (granted the spec would allow it). – MrAnima May 24 '23 at 14:02
3

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

Rune FS
  • 21,497
  • 7
  • 62
  • 96
1

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.

tia
  • 9,518
  • 1
  • 30
  • 44
0

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.

Adam
  • 327
  • 2
  • 4