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