Value of static variable not changed even after initializing the child class in java?

2806 views java
5

class par {
    static int y = 4;
}

class checks extends par {
    static {
        y = 5;
    }
}

public class check {
    public static void main(String args[]) {
        System.out.println(checks.y);// here printing 4
    }
}

As I invoked y static variable using the subclass.y still static block is not executing and value of y didn't get updated.

what could be the reason behind it?

As static is shared among all subclasses so the value is supposed to be updated. where am I getting wrong?

answered question

I know this comment is just noise, but it's worth saying. Excellent Question!

5 Answers

12

It seems the Classloader performs some optimization here, and since it determines that 'checks' isn't really used, it skips running its static block. If you force checks to be loaded, e.g., by instantiating an object of that type, you'll indeed see 5 printed.

posted this
5

The field y does not belong to class checks.

Even if it's accessed with checks.y, the compiler surely knows that the only class being used in all of this is par.

In other words, the class checks is not being used at runtime.

This is an example of the wrong of accessing static members through subclasses, for which you get a compile-time warning.

posted this
3

That's because the static block in the checks class doesn't get executed. Although you mention the class checks the JVM doesn't load it at all.

You can confirm this by adding another System.out.println inside the static block.

class checks extends par {

    static {
        System.out.println("Test");
        y = 5;
    }
}

The word Test will never get printed.

posted this
5

From JLS 12.4.1 :

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.

Since y is not declared in checks, none of the above criteria is satisfied.

Another way to illustrate this behavior :

class par {
    static int y = 4;
    static {
        System.out.println("par static constructor");
    }
}

class checks extends par {
    static int x = 6;
    static {
        System.out.println("checks static constructor");
        y = 5;
    }
}

public class check{
    public static void main(String args[]){
        System.out.println(checks.y);
        System.out.println(checks.x);
        System.out.println(checks.y);
    }
}

Output

par static constructor
4
checks static constructor
6
5

So after invoking checks.x that satisfies the second rule, the static constructor gets invoked.

posted this
4

As other mention, static block isn't executed because class isn't initialized as answered before,

Notice the class convention names start with an upper case

A clearer example to show Overriding class isn't used:

class Par {
    static int y = 4;
    public static void main(String args[]){
        System.out.println(checks.y);    // here printing 4
    }
}

class Checks extends Par {
   static {      
        y = 5;
    }
}

posted this

Have an answer?

JD

Please login first before posting an answer.