In Java, if a child class obscures the static parent variable with a child instance variable, which variable do the methods inherit?

This is probably bad, as described in Can a parent and child class in Java have the same instance variable? . (What if the name of the parent variable is changed? Then it will no longer be obscured.) However, I am still wondering if there will be shadow variables that are differently static / non-static. On the one hand, I would expect them to be the same variable name, so they will be obscured, but on the other hand, it seems that the compiler can distinguish between two based on static.

+7
source share
6 answers

From Java Language Specification :

If the expression name consists of one identifier, then there must be exactly one visible declaration, denoting either a local variable, parameter or field in the area at the point at which the Identifier. Otherwise, a compile-time error occurs.

If the declaration declares a final field, the value of the name is the value of this field. Otherwise, the value of the expression name is a variable declared by the declaration.

If the method in the superclass refers to a specific field (static or otherwise) of this class, then only this class declaration in the field will be in this area; any fields (static or other) of subclasses will not possess. Therefore, the method will always use the superclass field, even if the subclass inherits it and obscures this field.

This answer has been completely rewritten based on my new understanding of the question. Below is my first answer saved for posterity.

From Java Language Specification :

Declaring a d field, local variable, method parameter, constructor parameter or exception handler parameter with the name n shadows declarations of any other fields, local variables, method parameters, constructor parameters or exception handler parameters n that are in scope at the point where d occurs throughout the volume d.

This suggests that compilers should shade parent variables regardless of static.

Note that this does not apply to legacy methods that always use source variables regardless of whether their subclass obscures. I suspect this is not what you wanted to ask.

+4
source

According to the Java language specification:

If a class declares a field with a specific name, then declaring this field is said to hide any and all available field declarations with the same name in superclasses and superinterfaces of the class.

A hidden field can be obtained using a qualified name (if it is static)

JVM Specification

You can refer to the "Field Announcements" section.

+6
source

they will:

class Parent { static String x="static in parent"; String y="instance in parent"; } class Child extends Parent { static String y="static in child"; String x="instance in child"; void foo() { System.out.println("x "+x); System.out.println("super.x " + super.x); System.out.println("y "+y); System.out.println("super.y " + super.y); } } public class Main { public static void main(String[] args) { Parent parent=new Parent(); Child child=new Child(); System.out.println("Parent.x "+Parent.x); System.out.println("parent.x "+Parent.x); System.out.println("parent.y "+parent.y); System.out.println("child.x "+child.x); System.out.println("Child.y "+Child.y); System.out.println("child.y "+child.y); System.out.println("(Parent)child).x "+((Parent)child).x); System.out.println("(Parent)child).y "+((Parent)child).y); child.foo(); } } Parent.x static in parent parent.x static in parent parent.y instance in parent child.x instance in child Child.y static in child child.y static in child (Parent)child).x static in parent (Parent)child).y instance in parent x instance in child super.x static in parent y static in child super.y instance in parent 
+4
source

Take a look at the code below. If you want to access field from ChildClass , it will use its own member variable. If you want to access a static field from SuperClass , you must call it explicitly using SuperClass.field . STATIC_FIELD can be accessed directly since there is no ambiguity for the compiler.

  public class SuperClass{ static String field = "staticField1"; static String STATIC_FIELD = "staticField2"; //not possible to have a member field in this class -> compile error //String field = "memberField"; is not possible public SuperClass() { System.out.println( "field = " + field ); } } public class ChildClass extends SuperClass{ String field = "memberField"; public ChildClass() { System.out.println( "field = " + field );//access to member field //need to explicitly call SuperClass.field to access the static variable System.out.println( "SuperClass.field = " + SuperClass.field ); //no need to do this when there is no amibiguity System.out.println( "STATIC_FIELD = " + STATIC_FIELD ); } } 

See also 15.11.1 and 15.11.2 in here and 8.3 in here.

0
source
 public class Test { public static int MYNUMBER = 5; public Test() { } } public class TestChild extends Test { public int MYNUMBER = 8; public TestChild() { } } public class Main { public static void main(String[] args) { TestChild testChild = new TestChild(); // This would print out 8 System.out.println("in main test child: " + testChild.MYNUMBER); // This won't even compile if the MYNUMBER variable is overshadowed // If the MYNUMBER variable is not overshadowed it // would compile and // print out 5 // If we make MYNUMBER static also on TestChild, // it would compile and print out 8 System.out.println("in main TestChild.MYNUMBER " + TestChild.MYNUMBER); // This would print out 5 System.out.println(Test.MYNUMBER); } } 
0
source

Using the Eclipse compiler, methods from the parent class will still use member variables from the superclass, rather than shaded variables from the child class, as shown below. This is just a slightly modified version of the response to brainstorming.

 class Parent { static String x ="static in parent"; String y="instance in parent"; void bar() { System.out.println("x "+ x); System.out.println("y "+ y); } } class Child extends Parent { static String y ="static in child"; String x="instance in child"; void foo() { System.out.println("x "+x); System.out.println("super.x " + super.x); System.out.println("y "+y); System.out.println("super.y " + super.y); } } public class Main { public static void main(String[] args) { Parent parent=new Parent(); Child child=new Child(); System.out.println("Parent.x "+Parent.x); System.out.println("parent.x "+Parent.x); System.out.println("parent.y "+parent.y); System.out.println("child.x "+child.x); System.out.println("Child.y "+Child.y); System.out.println("child.y "+child.y); System.out.println("(Parent)child).x "+((Parent)child).x); System.out.println("(Parent)child).y "+((Parent)child).y); System.out.println("Member variable visibility in parent:"); parent.bar(); System.out.println("Member variable visibility in child:"); child.foo(); System.out.println("Member variable visibility in inherited methods:"); child.bar(); System.exit(0); } /* Output: Parent.x static in parent parent.x static in parent parent.y instance in parent child.x instance in child Child.y static in child child.y static in child (Parent)child).x static in parent (Parent)child).y instance in parent Member variable visibility in parent: x static in parent y instance in parent Member variable visibility in child: x instance in child super.x static in parent y static in child super.y instance in parent Member variable visibility in parent methods: x static in parent y instance in parent */ 
0
source

All Articles