Can "this" ever be null in Java?

JavaThis

Java Problem Overview


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?

Java Solutions


Solution 1 - Java

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 :

Solution 2 - Java

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

Solution 3 - Java

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;

Solution 4 - Java

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

Solution 5 - Java

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.

Solution 6 - Java

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.

Solution 7 - Java

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

Solution 8 - Java

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.

Solution 9 - Java

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.

Solution 10 - Java

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.

Solution 11 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBryce FischerView Question on Stackoverflow
Solution 1 - JavaColin HebertView Answer on Stackoverflow
Solution 2 - JavabragboyView Answer on Stackoverflow
Solution 3 - JavasactiwView Answer on Stackoverflow
Solution 4 - JavaTom Hawtin - tacklineView Answer on Stackoverflow
Solution 5 - JavaClaudiuView Answer on Stackoverflow
Solution 6 - JavaburkestarView Answer on Stackoverflow
Solution 7 - JavaRune FSView Answer on Stackoverflow
Solution 8 - JavaStephen CView Answer on Stackoverflow
Solution 9 - JavatiaView Answer on Stackoverflow
Solution 10 - JavaJohn HenckelView Answer on Stackoverflow
Solution 11 - JavaAdamView Answer on Stackoverflow