Shadowing Variables in Java Demystified

One of the meanings of the word “Shadow” in the Oxford Dictionary is “a weak or less good version”. Shadowing in Java is also something similar. One can shadow a variable in several ways. I would try to describe the one most comman ways which would trip most of us i.e. “Hiding an instance variable by shadowing it with a local Variable”. What exactly is Shadowing in Java? Shadowing is nothing but redeclaring a variable that’s already been declared somewhere else. The effect of Shadowing is to hide the previously declared variable in such a way that it may look as though you’re using the hidden variable, but you’re actually using the shadowing variable (The Code Snippet below will make it more clear). This most of the times happens by accident and causes hard-to-find bugs.

[java]
person class Person
{
int age=20;
void adjustAge(int age)
{
age=age+20;
System.out.println("The Age in adjustAge() is "+ age);
}
public static void main(String[] args)
{
Person p = new Person();
System.out.println("Age is: " +p.age);
p.adjustAge(p.age);
System.out.println("Adjusted Age is: " +p.age);
}
}
[/java]

The above code snippet is trying to change the age of the person, adding 20 to the existing age, which is done by the static method adjustAge(). So what will be the output? Any Gusses?

Output:

Age is: 20
The Age in adjustAge() is 40
Adjusted Age is:20

Code Demystified:

The line in the code which is bold and read in color is the main culprit i.e “age=age+20;“. Can anyone guess what is the line exactly doing? It is actually updating the local variable “age” and not the instance variable “age“, i.e the instance variable is shadowed by the Local Variable. And the scope of the Local Variable is the block of code in which it is declared. So, the last Print Statement actually access the unchanged instance variable “age“. Shadowing can also involve object references, in which case it becomes even more interesting to deal with.

For people preparing for SCJP, you can expect few questions on Shadowing.

Update: Have edited the post to add a relevant and useful examples. Earlier I had used static variables which weren’t that clear to understand. Also the corrected version of the above code would be to use:

[java firstline=”6″]
this.age=age+20;
[/java]

at Line 6 in the above code. So when you use “this” or class name for static variables- You refer to the field present in the class and not the local variable of the same name.

Advertisements

14 thoughts on “Shadowing Variables in Java Demystified”

  1. That’s the catch there. this is not required for static members. U can use the name of the class. If in the earlier example had Person.age would have been used in adjustAge() then we would have got the desired result.

    This is nothing but Shadowing.

    Like

  2. @all readers: The above comments were posted when the code example was using static fields. I have changed the example to use instance fields.

    Like

    1. Yeah, actually it should be flagged as an error. But looking at the scope of the age variable(part of the parameter list)- Its limited to the method. We cannot have the same variables declared in the same scope.

      Like

  3. as this stores the addre3ss (it act as a pointer ). now this contains the addrtess of calling objct i.e. p which work in stack and there for act on the address of age therfore vit update the value of age noe if we print p.age in main() then it wouyld give value=40, not 20

    Like

    1. Java is not pass by reference, instead its pass by value. For obejct references the value is nothing but the address of the object, but when it comes to primitives the value is the actual value.

      Now consider when an object reference is passed- it behaves as you have mentioned, but when an primitive value is passed- as in the given example, only the value of the primitive is copied and hence what ever changes made in the method are not reflected outside the method (as in the given example above) unless we use instance variables inside the method or the value is returned from inside the method.

      Like

  4. This example is not very good:
    1) p.age and adjustAge inline value are both ’20’, when it would be more clear to use a different value for each.
    2) adjustAge uses p.age as the argument, so it hides the fact what happens when adjustAge is called with a value not equal to p.age.

    Like

    1. For 1- The age in adjustAge is- age + 20, so its 40 and not 20.
      For 2- It doesnt work that way, when a method is invoked with few parameters, the values of the parameteres are passed to the method. I would suggest you to brush up the basics from the official Java tutorial.

      Like

  5. @MS:
    “Shadowing can also involve object references, in which case it becomes even more interesting to deal with.”

    Please explain.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s