Variable Hiding and Variable Shadowing in Java
Learn via video course
Overview
Java allows us to declare variables inside a class, method, block, or constructor. These variables declared can have different scopes in a program and can be of static or non-static type depending on the place it is declared.
Based on these criteria, Java variable types can be divided into Local Variables, Instance Variables and Class Variables. Variable shadowing and hiding happen when two variables in different scopes (local and global scopes, parent and child classes) are given the same name. In such a scenario, the value of the inner scope variable is used because it shadows/hides the value of the outer scope variable.
Scope
This article aims to:
- Help understand the concept of Local, Global and Class variables.
- Explain the concept of Variable Shadowing in Java.
- Illustrates Local Variable and Method Argument Shadowing in Java.
- Explains the concept of Variable Hiding in Java.
- Discuss Variable Hiding for static and non-static members of a class.
- Understand how to access hidden and shadowed variables.
- Differentiates between Variable Hiding and Variable Shadowing.
Introduction
Consider the below example, where two variables are declared with the name id. We may think that the below program throws an error because we declared two variables with the same name id. But fortunately, we won't get any errors, and the output will be 5678. Even though both the variables have the same name id, they are declared on different scopes, one in global scope and the other in local scope.
The id variable in global scope is accessible anywhere inside the class whereas the id variable in local scope is accessible only inside the main() method. The output is 5678 because of variable shadowing (i.e.) the id variable inside main() method shadows the id global variable and uses its own value.
Output
To understand variable shadowing and hiding, we must first know the different types of variables in java, how and where they are declared, their scope and visibility, etc. Java variables can be classified into three types.
- Local Variables
- Instance Variables
- Global Variables
Local Variables
Variables that are declared inside a method, block, or constructor are called local variables. The scope of the local variables is within the method, block, or constructor it is created. Local variables are created when the method, block, or constructor is executed and destroyed after finishing execution. Local variables cannot be declared as static.
Explanation:
In this example, sum is the local variable because it is declared inside the method findSum() and cannot be accessed outside.
Instance Variables
Variables that are declared inside a class but outside a method are called instance variables. Instance variables are not declared as static. Instance variables are created when an object is created and destroyed when the object is destroyed.
Explanation:
In this example, name is the instance variable because it is declared inside a class but outside a method. A new name variable is created for all Student objects created.
Class Variables
Variables that are declared as static inside a class but outside a method are called class variables. Class variables are declared as static.
There is only a single copy of the class variable per class regardless of the number of objects created. Class variables are created when the program starts and destroyed when the program ends. Class variables are also called static variables.
Explanation:
In this example, classVariable is the class variable because it is declared inside a class but outside a method and is declared static. classVariable is shared across all Variable objects created.
Variable Shadowing
Variable Shadowing happens when a variable in an inner scope is declared with the same name as a variable in the outer scope. In this case, the variable in the inner scope shadows (masks) the variable in the outer scope. Variable shadowing happens even when both the variables with the same name have different data types.
Example of Variable Shadowing
In the below example, there are two variables with the name name. One variable is inside the print() method (inner scope), and the other variable is inside the Student class (outer scope). The print method prints the name Steve Rogers instead of Tony Stark because the name local variable inside the print() method (inner scope) shadows the name instance variable inside the Student class (outer scope). So, the value of the variable that shadows (the one inside the print() method) is printed.
Output
Local Variable Shadowing
Local Variable Shadowing happens when a local variable (inner scope) shadows an instance variable (outer scope).
Output
In this example, there are two variables (one inside the display() method and the other inside class A) declared with the same name x. When we print the value of x inside display() method, it prints 2 because the local variable x inside display() method shadows the instance variable x inside class A.
Method Argument Shadowing
Method Argument Shadowing happens when a method parameter (inner scope) shadows an instance variable (outer scope).
Output
Explanation:
In this example, the parameter of the display() method and the instance variable of class A have the same name, x. When we print the value of x inside display() method, it prints 2 because the method parameter x of the display() method shadows the instance variable x inside class A.
Variable Hiding
Variable Hiding happens when a variable declared in the child class has the same name as the variable declared in the parent class.
In contrast, variable shadowing happens when a variable in the inner scope has the same name as the variable in the outer scope. The child class' variables tend to hide the parent class' variables when they have the same name. Variable hiding happens even when both the variables with the same name have different data types.
Example of Variable Hiding
Output
Explanation:
This example shows that the variable name in the Child class hides the variable name in the Parent class. When the display method of the Child class is called, it prints ChildClass. The super keyword should be used to access the name variable of the Parent class.
Variable Hiding for Static Variables
Static hiding happens between two variables are declared (one in parent class and the other in child class) with the same name and prefixed with the static keyword.
Output
Explanation:
In this example, the Parent class and Child class have two class variables, id and name. Though the child class' variables have the same name as the parent class, the displayId and displayName method of the child class prints its data. Here, the Child class' variables hide the Parent class variables. This variable hiding happened even for the variable id, which has same name and different type in the parent and child class.
Variable Hiding for Non-static Variables
Non-static hiding happens between two variables (one in parent class and the other in child class) declared with the same name and not prefixed with static keyword. Non-static variables are also called instance variables.
Output
Explanation:
In this example, both the Parent and Child class has a non-static variable name. The variable name in the Child class hides the variable name in the parent class. When we print the value of name inside Child class' displayName() method we get ChildClass instead of ParentClass. This is because the variable name inside Child class hides the value ofname inside Parent class and uses its own value.
Variable Hiding is Not the Same as Method Overriding
Method Overriding is a feature where a child class replaces the implementation of a method in the parent class with its implementation, whereas variable hiding hides the implementation.
Output
Explanation:
In this example, the Child class overrides the implementation of the print method in the Parent class (prints I am Parent) with its implementation (prints I am Child).
The child class variables only hide the parent class variables in variable hiding. Whereas, in method overriding, the child class methods replace the parent class methods. Consider the below example with an object childAsParent of type Parent pointing to an object of type Child.
Output
In variable hiding, the variables in child class hide the variables in parent class. So, when we access a variable from the parent's reference, which holds the child object, the parent class' variable is accessed. That's why childAsParent.name prints ParentClass.
In method overriding, the methods in child class replace those in parent class. So, when we access a method from the parent's reference, which holds the child object, the child class' method is accessed. That's why childAsParent.displayName() prints ChildClass.
How to Access Hidden and Shadowed Variable?
Access Shadowed Variable
The local variable shadows the instance variable if they both have the same name. this keyword should be used to access the shadowed instance variable. In the below example, the statement System.out.println(this.name) prints the value (Tony Stark) of the shadowed instance variable.
Output
Access Hidden Variable
The variable in the child class hides by the variable in the parent class if they both have the same name. super keyword should be used to access the hidden variable of the parent class. In the below example, the statement System.out.println(super.name) prints the value (ParentClass) of the hidden Parent class' instance variable.
Output
Difference Between Variable Shadowing and Variable Hiding
Variable Shadowing | Variable Hiding |
---|---|
Variable Shadowing occurs when a local variable and an instance variable within a class have the same name | Variable Hiding occurs when the variable in the child class has the same name as the parent class |
Variable Shadowing occurs within a class | Variable Hiding occurs between parent and child class |
Conclusion
- Variable shadowing occurs when a variable in an inner scope is declared with the same name as a variable in the outer scope. The variable in the outer scope shadows the variable in the inner scope.
- Local variable shadowing occurs when a local variable in the inner scope shadows an instance variable in an outer scope.
- Method argument shadowing occurs when a method parameter shadows an instance variable.
- The shadowed instance variable can be accessed using the this keyword.
- Variable hiding happens when a variable declared in the child class has the same name as the variable declared in the parent class.
- The hidden variable of the parent class can be accessed using the super keyword.
- Variable hiding is not the same as method overriding because, in variable hiding, the child class variables only hide the parent class variables. Whereas in method overriding the methods in the child class replaces the methods in the parent class.