Search code examples
javaperformancethisconventions

Any performance difference when using "this.xxx" to point to fields?


I'm just starting out in Java and I would like to make sure that my format and conventions are all OK from the get-go.

Basically, my teacher does this (which annoys me because it's unreadable)

public class MyClass
{   
    String name;
    int age;

    public MyClass (String n, int a)
    {
        name = n;
        age = a;
    }
}

Whereas I prefer to do something like this:

public class MyClass
{   
    private String name;
    private int age;

    public MyClass (String name, int age)
    {
        this.name = name;
        this.age = age;
    }
}

I just want to know if there is a performance difference between the two and which is more accepted.


Solution

  • The bytecode for accessing the fields is exactly the same in both cases. For the first one, javap -c returns:

    public MyClass(java.lang.String, int);
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   aload_1
       6:   putfield        #2; //Field name:Ljava/lang/String;
       9:   aload_0
       10:  iload_2
       11:  putfield        #3; //Field age:I
       14:  return
    
    }
    

    The second one:

    public MyClass(java.lang.String, int);
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   aload_1
       6:   putfield        #2; //Field name:Ljava/lang/String;
       9:   aload_0
       10:  iload_2
       11:  putfield        #3; //Field age:I
       14:  return
    
    }
    

    As you can see, they are functionally equivalent. The important thing is being able to understand the code. For constructors and setters, the standard in the Java community is to use name shadowing (the parameters share their names with the fields) and then the fields are accessed using this. as the qualifier. However, in logical methods, it's highly recommended that you never shadow fields. For example, I would avoid something like this:

    public class MyClass {
    
        // ...
    
        public int calculateAgeDifference(MyClass other) {
            int age = other.age; // This hides this.age, don't do this
            return this.age - age;
        }
    }
    

    Instead, do:

    int otherAge = other.age;
    

    This makes your code more readable. So only use shadowing in setters and constructors if you use it, I highly recommend avoiding it everywhere else.