The object that is “me”
When you call a.describe(), Java runs the code of describe on the particular object a refers to. Inside that code there must be some way to say “the object I am running on”. That way is the keyword this.
Within an instance method or a constructor, this acts as a special variable that holds a reference to the current object: the object whose method is being called, or whose constructor is running. You never declare it, and it is always available in an instance method or constructor.
Three uses matter in this course, and one restriction.
Use 1: reach the instance variable that a parameter hides
In Topic 3.8 you saw the bug that comes from giving a constructor parameter the same name as an instance variable: name = name; assigns the parameter to itself and the instance variable stays null. With this, you can keep the natural names and still be clear:
public class Pet
{
private String name;
private int age;
public Pet(String name, int age)
{
this.name = name;
this.age = age;
}
public String describe()
{
return name + " " + age;
}
public boolean sameObjectAs(Pet other)
{
return this == other;
}
public boolean olderThan(Pet other)
{
return this.age > other.age;
}
}
Now this.name means “the name instance variable of the current object”, and the plain name on the right means “the parameter”. The assignment this.name = name; copies the parameter into the instance variable. Run with new Pet("Rex", 4), describe() returns Rex 4, as the compiled program confirmed. Using the same name for the parameter and the instance variable is therefore safe provided you write this. in front of the instance variable.
The same technique works in methods. If a method had a parameter named age, this.age would still reach the instance variable.
Use 2: pass the current object as an argument
The keyword this can be used to pass the current object as an argument in a method call. This is how an object hands a reference to itself to another object.
public class Player
{
private String name;
public Player(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void becomeCaptainOf(Team t)
{
t.setCaptain(this);
}
}
public class Team
{
private Player captain;
public void setCaptain(Player p)
{
captain = p;
}
public Player getCaptain()
{
return captain;
}
}
Inside becomeCaptainOf, the call t.setCaptain(this) gives the Team a reference to the Player that is running the method.
p.becomeCaptainOf(team), this and p refer to the same Player, and t and team refer to the same Team. The call t.setCaptain(this) stores a reference to that Player in the Team.After p.becomeCaptainOf(team), the expression team.getCaptain() == p is true: the captain stored in the team is the very same object as p.
Use 3: compare the current object with another
Because this is a reference, you can compare it with another reference using ==, which tests whether they are the same object. And this.age reads the current object’s variable while other.age reads the other object’s (allowed because both are Pets and the code is inside Pet; see Topic 3.6):
public boolean sameObjectAs(Pet other)
{
return this == other;
}
public boolean olderThan(Pet other)
{
return this.age > other.age;
}
The restriction: class methods have no this
Class methods do not have a this reference. A static method is not called on an object, so there is no current object. Using this in one is a compile-time error:
public static int twice()
{
return this.value * 2;
}
The compiler reports non-static variable this cannot be referenced from a static context.
Worked example 1: tracing this inside methods
Task. Using the Pet class above, predict the output.
Pet a = new Pet("Rex", 4);
Pet b = new Pet("Tia", 7);
Pet c = a;
System.out.println(a.describe());
System.out.println(a.sameObjectAs(c) + " " + a.sameObjectAs(b));
System.out.println(a.olderThan(b) + " " + b.olderThan(a));
Step 1. a refers to Pet P1 (“Rex”, 4); b refers to P2 (“Tia”, 7); c = a; makes c another name for P1.
Step 2. a.describe(): this is P1, so it returns Rex 4.
Step 3. a.sameObjectAs(c): this is P1 and other (a copy of the reference in c) is P1: this == other is true. a.sameObjectAs(b): P1 versus P2 is false. Printed: true false.
Step 4. a.olderThan(b): this.age is 4 and other.age is 7: 4 > 7 is false. b.olderThan(a): this is now P2, so 7 > 4 is true. Printed: false true.
| Call | this is |
other is |
Comparison | Result |
|---|---|---|---|---|
a.sameObjectAs(c) |
P1 | P1 | P1 == P1 | true |
a.sameObjectAs(b) |
P1 | P2 | P1 == P2 | false |
a.olderThan(b) |
P1 (4) | P2 (7) | 4 > 7 | false |
b.olderThan(a) |
P2 (7) | P1 (4) | 7 > 4 | true |
The compiled program printed:
Rex 4
true false
false true
Check. The value of this is different in different calls: it is always the object before the dot. The same method code gave different results because this was a different object each time.
Worked example 2: passing this and returning this
Part A: passing this. Trace the captain example.
Team team = new Team();
Player p = new Player("Maya");
p.becomeCaptainOf(team);
System.out.println(team.getCaptain().getName());
System.out.println(team.getCaptain() == p);
teamrefers to a newTeamwhosecaptainisnull(the default for a reference type).prefers to aPlayerwithname“Maya”. The constructor usedthis.name = name;, so the name was stored correctly.p.becomeCaptainOf(team): inside the method,thisrefers to the Maya object andtto the team.t.setCaptain(this)stores that reference incaptain.team.getCaptain()returns the stored reference, sogetName()returnsMaya.team.getCaptain() == pcompares two references to the same object:true.
The program printed Maya and true.
Part B: returning this (an extension that follows from the same rule). A method may return this, which lets calls be chained.
public class Chain
{
private int total;
public Chain add(int n)
{
total += n;
return this;
}
public int getTotal()
{
return total;
}
}
Chain c = new Chain();
Chain d = c.add(2).add(3);
System.out.println(c.getTotal() + " " + d.getTotal() + " " + (c == d));
c.add(2) adds 2 to the object and returns a reference to that same object, on which .add(3) is called. The total is 5. Since d was assigned the returned reference, d is the same object as c: the output is 5 5 true, as the compiled program confirmed.
Check. Each result follows from one rule: this is the reference to the object before the dot in the call.
Common misconceptions
- “
thisalways refers to the same object.” It refers to the object the current method was called on, so it changes from call to call. - “
this.name = nameassigns the instance variable to the parameter.” The assignment goes right to left: the parameter’s value is stored into the instance variable. - “I must put
this.before every instance variable.” Only where a parameter or local variable hides it. Elsewhere it is optional and means the same. - “A class method can use
thisif the class has instance variables.” It cannot; class methods have nothis. - “
this == othercompares contents.” It compares references, so it istrueonly when both refer to the same object. - “
thisis a variable I declare.” It is provided automatically in instance methods and constructors.
Where this leads
That completes Unit 3. You can now design a class, write its constructors, methods, class variables and use this. For a mixed check, use the Unit 3 diagnostic and the Unit 3 review. Before moving on, work through the practice questions, the revision notes and the topic checklist. To revise the hiding problem that this solves, see Scope and Access. Unit 4 starts with Ethical and Social Issues Around Data Collection.
Quick questions
Do I always have to write this?
No. When no local variable or parameter hides an instance variable, name alone means the instance variable and this.name means exactly the same thing. You need this when a parameter or local variable has the same name, or when you need to pass or compare the current object itself.
What exactly is this?
A reference to the current object: the one on which the instance method was called, or the one being built by the constructor. If you write a.describe(), then inside describe the word this refers to the object a refers to.
Why can't a static method use this?
A class method belongs to the class and runs with no particular object, so there is no current object for this to refer to. The compiler reports non-static variable this cannot be referenced from a static context.
What does return this do?
It returns a reference to the current object. This lets calls be chained, as in c.add(2).add(3), because each call returns the same object for the next call to use.