Question

class Parent
{
  public static String sName = "Parent";
  static
  {
    System.out.println("Parents static block called");      
    sName = "Parent";
  }
}

class Child extends Parent
{
  public static String sName1;
  static
  {
    System.out.println("Childs static block called");       
    sName = "Child";
    sName1 = "Child";
  }
}

public class Inheritance
{
  public static void main(String []args)
  {     
    System.out.println(Child.sName);
    System.out.println(Parent.sName);
  }
}

In the above code snippet I have a 'Parent' class and a 'Child' class which extends Parent. I understand the fact that static variables are shared between parent and all of its subclasses. When I run the above program the output is

Parents static block called
Parent
Parent

I wonder why the Child's static block isn't executed even after executing 'System.out.println(Child.sName);'. I am not sure why only the parent class gets loaded and not the Childs class. Now when I modify the main() function as shown below the Child's class gets loaded.

public static void main(String []args)
{       
  System.out.println(Child.sName);
  System.out.println(Parent.sName);
  System.out.println(Child.sName1);   //sName is declared in Child class.
  System.out.println(Parent.sName);
}

The output now is shown below and is as expected. Now the Child class has to get loaded as we are making a reference to the static variable sName1 which is declared in Child class.

Parents static block called
Parent
Parent
Childs static block called
Child
Child

The static variable 'sName' now has 'Child' as its value. My question here is why doesn't the Child class gets loaded even after making a reference in the first line itself in the main function before modifying it?

Please advise.

Was it helpful?

Solution

From JLS

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, and an assert statement (§14.10) lexically nested within T is executed.

In the First case(first set of print staments), you have access only the sName variable only, and it's belong to Parent Class, so the child class was not initialized.

In the second set of print statements, You have access the sName1 variable, which belongs to Child class, so at this time, Child class was initialized.

It doesn't matter, even you have accessed the Child.sName, it actually refers the Parent.sName, so it won't load the Child class.

OTHER TIPS

class Parent
{
  public static String sName = "Parent";   // here you defining **sName** as static
  static
  {
    System.out.println("Parents static block called");      
    sName = "Parent";
  }
}


class Child extends Parent
{
  public static String sName1; // here you defining **sName1** as static
  static
  {
    System.out.println("Childs static block called");       
    sName = "Child";
    sName1 = "Child";
  }
}

so when you call System.out.println(Child.sName); sName is declare static in class parent. program will get value stored in sName(i.e sName = "Parent"; defined in static block inside class parent). so you go the result Parent.

and similar for other case

System.out.println(Child.sName);  
  System.out.println(Parent.sName);
  System.out.println(Child.sName1);   //sName is declared in Child class.
  System.out.println(Parent.sName);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top