Skip to main content

What is Variable Shadowing and Hiding in Java

Java allows us to declare a variable whenever we need it, We can categorize all our variables into 3 categories which have different-different scopes
  1. Instance Variables - Defined inside a class and have object level scope.
  2. Class Variables - Defined inside a class with static keyword, have class level scope common to all objects of the same class
  3. Local Variables - Defined inside a method or in any conditional block, have the block-level scope and only accessible in the block where it defined.
what-is-variable-hiding-shadowing

What is Variable Shadowing

Variable shadowing happens when we define a variable in a closure scope with a variable name and we have already defined a variable in outer scope with the same name.

In other words, when a local variable has the same name as one of the instance variable, the local variable shadows the instance variable inside the method block.

In the following example, there is an instance variable named x and inside method printLocalVariable(), we are shadowing it by the local variable x.

class Parent {

// Declaring instance variable by name `x`
String x = "Parent`s Instance Variable";

public void printInstanceVariable() {
System.out.println(x);
}

public void printLocalVariable() {
// Shadowing instance variable `x` by a local variable with same name
String x = "Local Variable";
System.out.println(x);

// If we still want to access instance variable, we do that by using `this.x`
System.out.println(this.x);
}
}

What is variable Hiding

Variable Hiding happens when we define a variable in child class with a variable name which we have already used to define a variable in the parent class. A child class can declare a variable with the same name as an inherited variable from its parent class, thus hiding the inherited variable.

In other words, when the child and parent class both have a variable with same name child class's variable hides parent class's variable.

In the below example, we are hiding the variable named x in the child class while it is already defined by its parent class.

class Child extends Parent {

// Hiding Parent class's variable `x` by defining a variable in child class with same name.
String x = "Child`s Instance Variable";

@Override
public void printInstanceVariable() {
System.out.print(x);

// If we still want to access variable from super class, we do that by using `super.x`
System.out.print(", " + super.x + "\n");
}
}

Variable Hiding is not same as Method Overriding

While variable hiding looks like overriding a variable similar to method overriding but it is not, Overriding is applicable only to methods while hiding is applicable variables.

In the case of method overriding, overridden methods completely replaces the inherited methods so when we try to access the method from parent's reference by holding child's object, the method from child class gets called. You can read more about overriding on Everything About Method Overloading Vs Method Overriding, Why We Should Follow Method Overriding Rules, How Does JVM Handle Method Overloading and Overriding Internally.

But in variable hiding child class hides the inherited variables instead of replacing, so when we try to access the variable from parent's reference by holding child's object, it will be accessed from the parent class.

When an instance variable in a subclass has the same name as an instance variable in a super class, then the instance variable is chosen from the reference type.

public static void main(String[] args) throws Exception {

Parent parent = new Parent();
parent.printInstanceVariable(); // Output - "Parent`s Instance Variable"
System.out.println(parent.x); // Output - "Parent`s Instance Variable"

Child child = new Child();
child.printInstanceVariable();// Output - "Child`s Instance Variable, Parent`s Instance Variable"
System.out.println(child.x);// Output - "Child`s Instance Variable"

parent = child; // Or parent = new Child();
parent.printInstanceVariable();// Output - "Child`s Instance Variable, Parent`s Instance Variable"
System.out.println(parent.x);// Output - Parent`s Instance Variable

// Accessing child's variable from parent's reference by type casting
System.out.println(((Child) parent).x);// Output - "Child`s Instance Variable"
}

In above example when we call overridden method printInstanceVariable() on parent while holding Child's object in it we can see the output is Child`s Instance Variable, Parent`s Instance Variable because in child class method is printing Child class's x variable and super.x.

But when we call System.out.println(parent.variable); on same parent reference which is holding child's object, it prints Parents Instance Variable because new Child() object keeps parent's x as well as child's x and hides parent's x. So, in this case, x is chosen from the class that is the reference type.

But if we wanted to access child's variable even if we are using parent reference we can do that by using (Child) parent).variable.

When our variables are private or is in another package and has default access, such variables are not visible outside that class and child class cannot access them. So there no confusion and that is why we should always stick to General Guidelines to create POJOs and declare our variables with private access and also provide proper get/set methods to access them.

You can find complete code on this Github Repository and please feel free to provide your valuable feedback.

Comments

  1. This blog is very useful for me and thanks for sharing
    Java Online Course

    ReplyDelete
  2. You overlooked the most important instruction regarding variable hiding...
    The general rule is: Don't do it!!!

    It just leads to bugs and confusion. Yes, it may be necessary sometimes, when you don't have control over the parent class' code, or something like that. But when you do it, you should always feel disappointment and a sense of failure. If you can avoid doing it, you probably should.

    ReplyDelete
    Replies
    1. Thanks for your comment!, I totally agree to you and that is why I have mentioned "When our variables are private or is in another package and has default access, such variables are not visible outside that class and child class cannot access them. So there no confusion and that is why we should always stick to General Guidelines to create POJOs and declare our variables with private access and also provide proper get/set methods to access them."

      I know it creates confusion and that's reason we should be aware of it in the first place.

      Delete

Post a Comment

Popular posts from this blog

Why an outer Java class can’t be static

In a previous blog , I talked about why we can not define an outer class using private or protected keywords. If you have not read it, please go ahead and give it a look. I this article I will talk what is the use of the static keyword, why an outer Java class can’t be static, why it is not allowed in Java to define a static outer class. In order to understand that first, we need to understand what is the static keyword used for, what purpose it solves and how does it works. What does static keyword do Every Java programmer knows that if we need to define some behavior (method) or state (field) which will be common to all objects we define it as static. Because static content (behavior or state) does not belong to any particular instance or object, it will common to all objects and all objects are free to change any static field and every change will be visible to every object. We do not need to create any object of the class to access a static field or method, we can directly...

Why Single Java Source File Can Not Have More Than One public class

According to Java standards and common practices we should declare every class in its own source file. And even if we declare multiple classes in the single source file (.java) still each class will have its own class file after compilation. But the fact is that we can declare more than one class in a single source file with below constraints, Each source file should contain only one public class and the name of that public class should be similar to the name of the source file. If you are declaring the main method in your source file then main should lie in that public class If there is no public class in the source file then main method can lie in any class and we can give any name to the source file. If you are not following 1st constraint then you will receive a compilation error saying “ The public type A must be defined in its own file ”.  While if you are not following the second constraint you will receive an error “ Error: Could not find or load main class User ” after ...

How Does JVM Handle Method Overloading and Overriding Internally

In my previous article Everything About Method Overloading Vs Method Overriding , I have discussed method overloading and overriding, their rules and differences. In this article, we will see How Does JVM Handle Method Overloading And Overriding Internally, how JVM identifies which method should get called. Let’s take the example of parent class  Mammal and a child  Human classes from our previous blog to understand it more clearly. public class OverridingInternalExample { private static class Mammal { public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); } } private static class Human extends Mammal { @Override public void speak() { System.out.println("Hello"); } // Valid overload of speak public void speak(String language) { if (language.equals("Hindi")) System.out.println("Namaste"); else System.out.println("Hello"); } @...