What is .. this ?

| 3 min read

He asked me about that word again, he was happy learning and advancing in his Java programming course .. he told me that
he started to reach OOP and the concepts behind it as he said:

Ok, I think I am getting to grasp the concepts of OOP now,
I think I am fully understanding what is a class and why we use classes,
and how to create instances from these classes .. But I can't get what is the use of this keyword actually

That brought me years ago when I was watching an online course and got hit by this , days later I was in OOP lecture
where the professor explained the same keyword this , I felt that I got more info but I thought that this thing is very complicated
, so thought my colleagues !

As many programmers I don't always remember when did I learn specific topics, but I think I know more about OOP now, and I keep receiving the
same question about this again and again from fellow colleagues and fresh guys learning programming, Every time I got asked this question I answer it, I am answering it but with different way of explanation each time, I feel I am missing something while explaining.

Lately I noticed a problem happening each time I explain this to someone, people are getting to learn about objects
and it's design, but rarely someone get the concept of instance creation and how Java deals with references .

Here I am trying to get into that point of Object creation in Java, let's try to explain this using cookies !

class Cookie {

int radius;
boolean baked;

public Cookie(int radius,boolean baked) {
this.radius = radius;
this.baked = baked;
}

public static void main(String[] args) {
Cookie c1 = new Cookie(10,false);
Cookie c2 = new Cookie(5,true);
}

}

In the previous example we just created a Cookie class and created two instances c1 , c2 from it, Java just allocated space for those 2 instances in memory and stored a reference of that instance location in the variables c1 and c2 respectively, that means Java doesn't store whole Objects in variables, it just stores a reference of that instance .

Referring to toString() default implementation it states that the returned value of the method is :

getClass().getName() + '@' + Integer.toHexString(hashCode())

We can use hashCode() in this example, but in general it could be overridden, so we will use the more generic way to get a unique identifier of instances by using System.identityHashCode(Object) :

System.out.println(Integer.toHexString(System.identityHashCode(c1)));
System.out.println(Integer.toHexString(System.identityHashCode(c2)));

That should print something like this to the console, which means we can check the reference of the Objects

> 2a139a55
> 15db9742

Now, Let's have some normal changes to our instances, changing their attributes' values

System.out.println(Integer.toHexString(System.identityHashCode(c1)));
System.out.println(Integer.toHexString(System.identityHashCode(c2)));

> 2a139a55
> 15db9742

c1.radius = 120 ;
c2.baked = false;

System.out.println(Integer.toHexString(System.identityHashCode(c1)));
System.out.println(Integer.toHexString(System.identityHashCode(c2)));

> 2a139a55
> 15db9742

Ok, Nice changing the values and modifying the instance doesn't change the reference saved in the variable, and that makes sense, it still points to the same location in memory, and when we change some value it gets to that location, modifies the values we want and then return back, the memory location is still the same for later modifications/readings, let's try to change the location that the variable is pointing to, for example let's assign the address stored in c2 to c1

c1 = c2;

System.out.println(Integer.toHexString(System.identityHashCode(c1)));
System.out.println(Integer.toHexString(System.identityHashCode(c2)));

> 15db9742
> 15db9742

This clearly indicates the references thing, now the two variables are pointing to the same location in memory and they read the same values and if we modify any attribute it will modify the same data

Let's go and try to modify our Cookie class implementation a bit, by adding a statement to print this hashCode into it's constructor :

public Cookie(int radius,boolean baked) {
this.radius = radius;
this.baked = baked;
System.out.println(Integer.toHexString(System.identityHashCode(this)));
}

and in our main method let's create new instances again :

c1 = new Cookie(12,false);
c2 = new Cookie(32,true);

> 2a139a55
> 15db9742

System.out.println(Integer.toHexString(System.identityHashCode(c1)));

> 2a139a55

System.out.println(Integer.toHexString(System.identityHashCode(c2)));

> 15db9742

That's pretty interesting, as you can see this is pointing to the same memory location of the instance that is using the constructor right now, we can push it to more interesting stuff, like returning this from a method, let's make this last modification on our Cookie class

public Cookie getMe(){
return this;
}

as you compile this it works !, that's because of this is carrying the reference of the instance that calls this method, let's test this in our main method

Cookie thisCookie = c1.getMe();

System.out.println(Integer.toHexString(System.identityHashCode(c1)));
System.out.println(Integer.toHexString(System.identityHashCode(thisCookie)));

> 2a139a55
> 2a139a55

that's why this is pretty useful to get a reference to the calling instance in your class, allowing you to modify and manipulate the instance in runtime based on your class definitions and methods .