Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable shadowing in Java [duplicate]

Tags:

java

I am having some doubts about this Java code. The output it gives is "furry bray". My questions:

  1. Why do i get this output?
  2. How can I access the String object reference "name" in ZooKeeper class?
  3. If it has something to do with variable shadowing, then which variable is being shadowed?

Code:

class Mammal {    String name = "furry ";    String makeNoise() { return "generic noise"; }  }  class Zebra extends Mammal {    String name = "stripes ";    String makeNoise() { return "bray"; }  }  public class ZooKeeper {    public static void main(String[] args) { new ZooKeeper().go(); }    void go() {      Mammal m = new Zebra();      System.out.println(m.name + m.makeNoise());      //Output comes as "furry bray". Please explain this.      //And how can we access the name variable, the one having "stripes " in it.      //Does it have something to do with Variable Shadowing?    }  } 
like image 488
Prateek Singla Avatar asked Jun 05 '13 13:06

Prateek Singla


People also ask

What is variable shadowing in Java?

If the instance variable and local variable have same name whenever you print (access) it in the method. The value of the local variable will be printed (shadowing the instance variable).

What is the difference between variable shadowing and 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.

How do you avoid variable shadowing?

How to avoid variable shadowing? To modify a global variable, and avoid variable shadowing python provides global keyword which tells python to use the global version of the variable, instead of creating a new locally scoped variable.

How do you overcome an instance variable hiding in Java?

In Java, if there is a local variable in a method with the same name as the instance variable, then the local variable hides the instance variable. If we want to reflect the change made over to the instance variable, this can be achieved with the help of this reference. Example: Java.


2 Answers

Variables aren't polymorphic. When you access m.name, that will always use the Mammal.name field which is part of that object, regardless of the execution-time type of the object. If you need to get access to Zebra.name, you need an expression with a compile-time type of Zebra.

The makeNoise method is called virtually though - the implementation used at execution time does depend on the type of the object.

Note that if you make all your fields private - which is generally a good idea anyway - this doesn't end up being an issue.

This is actually hiding rather than shadowing. See JLS section 8.3 for details on hiding, and section 6.4.1 for shadowing. I can't say that I always keep the differences straight...

like image 67
Jon Skeet Avatar answered Sep 20 '22 17:09

Jon Skeet


Output comes as "furry bray". Please explain this.

fields in java programs are not accessed via dynamic lookup. Instead they are resolved statically while compile time. That's why you are getting furry for m.name. Whereas, methods in java programs are accessed via dynamic lookup. That's why you are getting bray for m.makeNoise().

And how can we access the name variable, the one having "stripes " in it?

And if you want to access Zebra.name , you should type cast m to 'Zebra'.This would look like this:

System.out.println(((Zebra)m).name + m.makeNoise()); 

UPDATE
The phenomena that is exhibiting here is the result of Fields Hiding rather than variable shadowing.

like image 32
Vishal K Avatar answered Sep 20 '22 17:09

Vishal K