2

I was trying to understand static variables in Java and what I see is following behaviour

public class TestParent {
     protected static String name = "parent";
}

public class TestChild extends TestParent{
    public TestChild(){
          super.name="child";
    }
}

Now if

TestParent tp = new TestParent();

output:

parent

else if,

TestParent tp = new TestChild();

output: child

Can someone explain to me what exactly is happening? I know this question sounds very simple but I am not able to understand the reason.

Thanks.

AlienOnEarth
  • 747
  • 7
  • 14
  • The `super.name` is a "lie". This is why `((TestParent)null).name = "foo";` would also work. – user2864740 Oct 02 '15 at 04:20
  • Can you please explain why ((TestParent)null).name = "foo"; would work? – AlienOnEarth Oct 02 '15 at 04:22
  • 2
    See http://stackoverflow.com/questions/11579953/static-fields-on-a-null-reference-in-java .A static field can be accessed on *any* expression of the correct type; the actual instance - or lack of - is irrelevant. It is generally best to only use the "obviously static" form (ie. `TestParent.name`) to avoid confusion such as this. – user2864740 Oct 02 '15 at 04:24
  • @AlienOnEarth Added in my answer – Suresh Atta Oct 02 '15 at 04:25

2 Answers2

1

static fields never attach to instances rather than classes. They only need type to access.

Since super references to the type TestParent, it looks like you are overriding it but you can do that from out side Child as well with it's Class name (TestParent).

Inshort to access static fields you just need type, no need of instance. For ex

TestParent test = null;
System.out.println(test.name);

That works because the type of test is TestParent it invoke name on that type.

Why does Java compiler allow static variable access through null object?

Update on your question update :

When you do TestParent tp = new TestChild();

You are invoking child class constructor and in that constructor you are doing

 super.name="child";

Hence that is changing the value of name to child

Though you are changing in child, since static variables are bind to Parent class and not to instances, you can see the change across all the instances.

Community
  • 1
  • 1
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
0

Static fields doesn't get inherited, which means child classes don't get their own copy of those static fields they only existed once which in in the parent class.

Now when you are doing this. TestParent tp = new TestParent();

it will print parent. Because value parent is assigned to the field name and you haven't called new TestChild(); yet, which will change the value.

So when you are doing

TestParent tp = new TestChild();

inside the TestChild constructor the value of name being changed to child. here you are changing the variable of the class TestParent and the change affected in the name variable of class TestParent. That's why you are getting child when printing.

You can do a little more experiment. if you do

TestParent tp = new TestChild();

first and print (which will give child as output ), and then

TestParent tp = new TestParent();

and print it will also give child as output.

Saif
  • 6,804
  • 8
  • 40
  • 61