Shadowing and this keyword.

Photo by Isai Ramos on Unsplash

Shadowing and this keyword.

Shadowing problem and 'this' keyword in Java

Shadowing, if we go into understanding the literal meaning of this word, it would roughly come as "covering something else in such a way that it is no longer relevant, visible or gets hidden".

In this article, we will understand why are we discussing this concept in Java, how it occurs, and how we overcome it through examples.

But first, can you predict the output of the following?

class Student{
    private int age = 24;
    private String name = "SHISHIR" ;

    void setData(int age, String name){
        age = age;
        name = name;
    }

    void result(){
        System.out.println("The Age is : " + age + " and name is : " + name);
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj = new Student();
        obj.setData(55, "Babu Rao");
        obj.result();
    }
}

if you said, the output is,

"The age is : 55 and name is : Babu Rao"

then you to go further in this article, why is the above not correct.

The Correct output would be:

The Age is : 24 and name is : SHISHIR

Allow me to explain how further.

Understanding shadowing

In the above example, we had 4 variables, 2 were instance variables and 2 were local, how? let's see.

Post that, you call the method to set the data, using setData giving it two arguments 55 and 'Babu Rao'.

Student obj = new Student();
obj.setData(55, "Babu Rao");

Now, the method setData should take those values and update the age and name variables, right?

Right, but which type of variable is 'age'? and which 'age' variable are you referring to, the instance one? or the local one?

This confusion is happening because these two variables are having the same name as the parameters, which results in a name clash, in such scenarios, JVM always gives priority to the local variables. Hence, the variables on the left side of the assignment operator would be considered the local variables and values from the right would be assigned to them, as a result, the values of the instance variables will not get updated.

Note: For these local variables, the scope is within their method block only, they cannot be accessed outside that block.

Now, can we print to see what value the local variables hold? and observe the difference via outputs? Yes!! we will add a few lines to the above code, to get an output, which makes things even more clear.

See, the code snippet below, now we are printing the values of the variables in the setData method, let's see what comes as the output.

class Student{
    private int age = 24;
    private String name = "SHISHIR" ;

    void setData(int age, String name){
        age = age;
        name = name;
        System.out.println("From setData method age and name are : " + age + " and " + name);
    }

    void result(){
        System.out.println("The values for Instance variables are : " + age + " and " + name);
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj = new Student();
        obj.setData(55, "Babu Rao");
        obj.result();
    }
}

OUTPUT :

From setData method age and name are : 55 and Babu Rao
The values for Instance variables are : 24 and SHISHIR

This makes it clear that the values are being updated in local variables and are not affecting the instance variables.

How do we overcome this issue?

The first solution coming to your mind would be to just not give the parameters the same name as that of the instance variables and we will not have this issue. Well yes, that would indeed not give you this unexpected result. However, then again you would be using different parameter names for a variable and that again leads to non-standardization.

Also while working with multiple classes, if you keep the variable names different in each class and method for the same thing, after a while it would become extremely difficult to keep track of.

Hence, it is better to use the same names only for parameters, but then again we would face this shadowing issue, how do we overcome this then? To overcome this issue, we use the 'this' keyword.

'this' keyword

The 'this' keyword in the class, refers to the current object in any method/constructor. That's it!

The syntax for it is :

this.age = age;
this.name = name;

What is being done here is that now, the 'this.age' is referring to the current class's 'age' instance variable, and the value from the method is now being assigned to it.

There is no longer a name clash now, as we have specifically told JVM with the help of 'this' keyword, which variable are we referring to. Let's try to run it once and see the output for ourselves.

We will use the same above code, this time with 'this' keyword, what do you think? The output will be different?

class Student{
    private int age = 24;
    private String name = "SHISHIR" ;

    void setData(int age, String name){
        this.age = age;
        this.name = name;
        System.out.println("From setData method age and name are : " + age + " and " + name);
    }

    void result(){
        System.out.println("The values for Instance variables are : " + age + " and " + name);
    }
}

public class MyTest{
    public static void main(String []args){
        Student obj = new Student();
        obj.setData(56, "Raju");
        obj.result();
    }
}

OUTPUT:

From setData method age and name are : 56 and Raju
The values for Instance variables are : 56 and Raju

Indeed, the output is now as expected and the instance variable is getting updated.

Conclusion

In this article, we have seen what is the shadowing problem, here it is happening when we keep the variable name and the parameter name the same. How we resolve it using the 'this' keyword, which refers to the instances of the current class.



Thanks for coming this far in the article, I Hope I was able to explain the concept well enough. If in any case, you face any issues please feel free to reach out to me, I'd be happy to help.

You can always connect to me over LinkedIn to share feedback or queries by clicking here.