The “this” keyword

  • “this” can be used inside any method to refer to the current object
  • “this” is always a reference to the object on which the method was invoked
  • “this” is a keyword in Java and contains the value of the current object inside wherever it’s being returned
  • e.g.

    Outside a class, the name of the calling object is known, for example;

    ob.addDate(); // call the addDate method on the object ob

    but, inside the class, we don’t have to use the object name, ob, we can just use “this”

    So,

    The keyword “this” stores a reference to the object that is currently in action.

    If a class has multiple constructors, it’s better to implement them using “this” as much as possible. A constructor with no or a few arguments can invoke the constructor with more arguments using “this”. This simplifies code and makes it easier to maintain.

    Java requires that the “this” keyword appears first in the constructor before any other statements.

    An example:

    public class ThisExample {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Account obj = new Account();
    		obj.setData(3, 5);
    		obj.showData();
    	}
    
    }
    
    class Account{
    	int a;
    	int b;
    	
    	public void setData(int a, int b){
    		a=a;
    		b=b;
    	}
    	
    	public void showData(){
    		System.out.println("Value of a= "+a);
    		System.out.println("Value of b= "+b);
    	}
    }
    

    The output is:

    Value of a= 0
    Value of b= 0

    Although we wouldn’t expect this.

    As you can see, the local variables int a and int b in the method setData has the same name as the instance variables (int a and int b) in the Account class. During execution, the compeller is confused with

    a=a
    b=b

    it doesn’t know whether a on the left side of the operator is the instance variable, or the local variable. The problems can be overcome using “this”.

    public class ThisExample {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Account obj = new Account();
    		obj.setData(3, 5);
    		obj.showData();
    	}
    
    }
    
    class Account{
    	int a;
    	int b;
    	
    	public void setData(int a, int b){
    		this.a=a; // it's like saying obj.a = a
    		this.b=b; // it's like saying obj.b = b
    	}
    	
    	public void showData(){
    		System.out.println("Value of a= "+a);
    		System.out.println("Value of b= "+b);
    	}
    }
    

    Now outputs:

    Value of a= 3
    Value of b= 5

    Because
    now the compiler knows that the a on the left hand side is the instance variable, whereas a on the right hand side is the local variable and
    now the compiler knows that the b on the left hand side is the instance variable, whereas b on the right hand side is the local variable.

    Suppose you were smart enough to choose different names for your instance variables and local variables as below:

    public class ThisExample {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Account obj1 = new Account();
    		obj1.setData(3, 5);
    		
    		Account obj2 = new Account();
    		obj2.setData(8, 9);
    		
    		obj1.showData();
    		obj2.showData();
    		
    	}
    }
    
    class Account{
    	int a;
    	int b;
    	
    	public void setData(int c, int d){
    		a=c; 
    		b=d;
    	}
    	
    	public void showData(){
    		System.out.println("Value of a= "+a);
    		System.out.println("Value of b= "+b);
    	}
    }
    

    Output:

    Value of a= 3
    Value of b= 5
    Value of a= 8
    Value of b= 9

    In the above example, how does the compiler determine whether it’s to work on the instance variables of obj1, or obj2?

    The compiler implicitly appends the instance variables with the “this” keyword. i.e.

    this.a=c;
    this.b=d;

    .. effectviely

    obj1.a=c;
    obj1.b=d;

    or

    obj2.a=c;
    obj2.b=d;

    .. depending on which object is calling it.

    GOOD EXAMPLE 1 (Instance variable hiding/Instance variable shadowing)

    public class ThisKeyword {
    
    	public static void main(String[] args) {
    		
    		MyClass myClass1 = new MyClass();
    		myClass1.number=8;
    		myClass1.display();
    		System.out.println("myClass1= "+myClass1);
    
    		MyClass myClass2 = new MyClass();
    		myClass2.display();
    		System.out.println("myClass1= "+myClass2);
    	}
    
    }
    
    
    class MyClass
    {
    	int number=1;
    	
    	public void display()
    	{
    		int number=5;
    		System.out.println(number);
    		System.out.println("this keyword "+this);
    		System.out.println("instance variable "+this.number);
    	}
    }
    

    Outputs:

    5
    this keyword MyClass@3343c8b3
    instance variable 8
    myClass1= MyClass@3343c8b3
    5
    this keyword MyClass@272d7a10
    instance variable 1
    myClass1= MyClass@272d7a10

    GOOD EXAMPLE 2 (“this” and constructors)

    public class ThisKeyword {
    
    	public static void main(String[] args) {
    		
    		MyClass myClass1 = new MyClass(6,"James");
    		
    		myClass1.showNumber();
    		myClass1.showString();
    	}
    }
    
    class MyClass
    {
    	int number=1;
    	String s;
    	
    	// constructor
    	public MyClass(int number, String s)
    	{
    		// instance variable = local variable
    		this.number=number;
    		// instance variable = local variable
    		this.s=s;
    	}
    	
    	public void showNumber()
    	{
    		System.out.println(number);
    	}
    	
    	public void showString()
    	{
    		System.out.println(s);
    	}
    }
    

    Outputs:
    6
    James

    Further example of using “this” in constructors

    public class ThisKeyword {
    
    	public static void main(String[] args) {
    		
    		MyClass myClass1 = new MyClass(6);
    		myClass1.showVariables();
    		
    		MyClass myClass2 = new MyClass(6,4);
    		myClass2.showVariables();
    		
    		MyClass myClass3 = new MyClass(6,4, false);
    		myClass3.showVariables();
    		
    	}
    
    }
    
    
    class MyClass
    {
    	int x;
    	int y;
    	boolean bool;
    	
    	MyClass(){
    		this.x=1;
    		this.y=2;
    		this.bool=true;
    	}
    	
    	MyClass(int x){
    		this.x=x; // instance variable value = local variable value
    		this.y=2;
    		this.bool=true;
    	}
    	
    	MyClass(int x, int y){
    		this.x=x; // instance variable value = local variable value
    		this.y=y; // instance variable value = local variable value
    		this.bool=true;
    	}
    	
    	MyClass(int x, int y, Boolean b){
    		this.x=x; // instance variable value = local variable value
    		this.y=y; // instance variable value = local variable value
    		this.bool=b; // instance variable value = local variable value
    	}
    	
    	public void showVariables(){
    		System.out.println (" x="+x+" y="+y+" bool="+bool);
    	}
    }
    

    Output:

    x=6 y=2 bool=true
    x=6 y=4 bool=true
    x=6 y=4 bool=false

    The above code is very verbose and looks confusing, we can use the “this” keyword on the BIGGEST constructor as follows

    public class ThisKeyword {
    
    	public static void main(String[] args) {
    		
    		MyClass myClass1 = new MyClass(6);
    		myClass1.showVariables();
    		
    		MyClass myClass2 = new MyClass(6,4);
    		myClass2.showVariables();
    		
    		MyClass myClass3 = new MyClass(6,4, false);
    		myClass3.showVariables();
    		
    	}
    
    }
    
    
    class MyClass
    {
    	int x;
    	int y;
    	boolean bool;
    	
    	MyClass(){
    		this(1,2,true); //when this statement runs, the biggest constructor (***) will be called
    	}
    	
    	MyClass(int x){
    		this(x,2,true); //when this statement runs, the biggest constructor (***) will be called
    	}
    	
    	MyClass(int x, int y){
    		this(x,y,true); //when this statement runs, the biggest constructor (***) will be called
    	}
    	
    	MyClass(int x, int y, Boolean b){ // (***)
    		this.x=x;
    		this.y=y;
    		this.bool=b;
    	}
    	
    	public void showVariables(){
    		System.out.println (" x="+x+" y="+y+" bool="+bool);
    	}
    }
    

    Outputs (the same as above):

    x=6 y=2 bool=true
    x=6 y=4 bool=true
    x=6 y=4 bool=false

    Leave a Reply