4

This seems like it could be a common question but I searched SO and Google and couldn't find quite what I'm looking for:

What is the overhead of calls to the this keyword in Java? I know in C++ there is some minimal overhead due to dereferencing the current object pointer. Does Java incur the same kind of overhead? Is it less optimal to make multiple calls to this. It's mostly a question of readability vs. optimization.

Maroun
  • 94,125
  • 30
  • 188
  • 241
Mark Hazlewood
  • 453
  • 1
  • 3
  • 7
  • 2
    Most likely it does not matter at all, and you get the same bytecode whether you use `this.` or not. Try disassembling your code with `javap -c`, I would not be surprised if the bytecode is exactly the same when you use `this.` and when you don't. – Jesper Dec 05 '13 at 15:04
  • 1
    Overhead compared to what? You mean `this.a; this.b; this.c;` vs. `T tmp = this; tmp.a; tmp.b; tmp.c;`? – Oliver Charlesworth Dec 05 '13 at 15:04
  • 2
    `this` isn't an operator. Are you talking about accessing instance variables/methods, or chaining to constructors? If you could give us a concrete example - ideally of "which is more expensive, X or Y" - that would help. – Jon Skeet Dec 05 '13 at 15:04
  • 1
    It is compiled to identical byte code – Richard Tingle Dec 05 '13 at 15:05
  • 1
    @Oli: Compared to not prefixing the instance field and methods with `this.`. It can be inferred from the context. ;) – Andrei Nicusan Dec 05 '13 at 15:06
  • Are you comparing local variable access time to instance variable access time, or something else? – Joni Dec 05 '13 at 15:06
  • It tends to be interpreted languages where this is an issue rather than compiled languages – Richard Tingle Dec 05 '13 at 15:09
  • @Jesper I did not know about that ability in Java, thanks I will use it in the future. – Mark Hazlewood Dec 05 '13 at 15:45

4 Answers4

6

None whatsoever. They both produce exactly the same bytecode. For example, this:

package test;

public class T {

    int a=0;

    public T() {
        System.out.println(a); //this line
    }

    public static void main(String[] args) {
        new T();
    }

}

...produces:

public class test.T {
  int a;

  public test.T();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: iconst_0      
       6: putfield      #2                  // Field a:I
       9: getstatic     #3                  // Field     java/lang/System.out:Ljava/io/PrintStream;
      12: aload_0       
      13: getfield      #2                  // Field a:I
      16: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
      19: return        

  public static void main(java.lang.String[]);
    Code:
       0: new           #5                  // class test/T
       3: dup           
       4: invokespecial #6                  // Method "<init>":()V
       7: pop           
       8: return        
}

...regardless of whether the line marked this line uses a or this.a. (Try it if you like - compile the above code both ways and compare both class files with javap -c.) Considering they produce exactly the same bytecode, there's no way there can be differences in performance.

Michael Berry
  • 70,193
  • 21
  • 157
  • 216
2

If you mean something like using

private String myString;
public void doStringStuff() {
    this.myString xxxxx;
}

instead of

private String myString;
public void doStringStuff() {
    myString xxxxx;
}

then the bytecode will be the same, but it will compile a tiny tiny fraction faster, as the compiler does not need to check through local variables looking for a match.

Matt
  • 3,303
  • 5
  • 31
  • 53
2

Probably the same bytecode will be generated if you use this where you don't really have to.

But sometimes you must use this keyword (For example when you have name conflicts):

private int a;
public MyClass(int a) {
    this.a = a; //this is a must
}

For clarity, I think it's a matter of taste. Some programmers prefer to see it, some don't. Also note that this is a keyword, not an operator.

Tip: Don't waste time on performance issues for really small things..

Maroun
  • 94,125
  • 30
  • 188
  • 241
0

There is no difference. If you call in class A from method a() to method b(), these are exactly the same:

public void a()
{
    this.b();
    b();
}

The overhead you are talking about is when it dereferences the pointer to the object to read or write variables. Imagine you want to write to class A the classmember a, you would do:

A x = new A();
x.a = 3;

Here, you encounter the overhead: when writing to x.a, it has to find out where that exactly is. To find that out, it has to make the sum of x and the offset of the variable a inside that class. So, it is probably making a sum like: x + 0x10. Now, it can write to the address that corresponds with the sum. That is the overhead you were talking about.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287