Monday, September 12, 2016

Java Annotation PostConstruct and Inheritance

It is quite confusing when the Java inheritance is mingled with the PostConstruct annotation. Based on my tests, I found the following. Suppose there are two classes.
  class A {
    @PostConStruct
    private void init(){
 
    }
  }

  class B extends A {

   }


Case 1

For the above case, the execution order is
  1. Constructor of A
  2. Constructor of B
  3. init method of A.
So the annotation @PostConstruct is inherited even when the annotated method is private in the parent class.

Case 2

Now if the class B has its own @PostConstruct method such as the following:
      @PostConstruct
      private void my_init(){
      }
   
Then the init() method of A will not be called. Instead, my_init() is called. So it seems that in the class hierarchy, only one PostConstruct annotated method is called.

Case 3

Now if the class B does not have its own @PostConstruct. But it overrides the @PostConstruct annotated method in its parent class.
  class A {
    @PostConStruct
    public void init(){
       System.out.println("A init()");
    }
  }

  class B extends A {
   @Override
   public void init(){
      System.out.println("B init()");
    }
   }
In this case the @PostConstruct method init() is called. But the init() method used is from class B. So it will print "B init()". Note that if the init() method in class A is private, then "A init()" will be printed out. In this case, the init() method of B is not an override method. Actually you have to remove its @Override annotation. Otherwise it won't compile.

Conclusion

In summary, if there is a method with the annotation @PostConstruct in a class C or its parent classes, then the annotated method will be called after the constructor of C is called. In case that @PostConstruct appears in multiple classes in the class hierarchy, the one closest to the class C will be called. Furthermore, if that annotated method is overridden by its subclasses, then the overriding method will be called. Of course, I think it is bad to declare the @PostConstruct annotated method as public or protected. It should be private so it won't be overridden.

1 comment:

  1. case 2 is wrong. In fact, the super class postconstruct will be invoked before the child class's postconstruct. But make no mistake, both of them are going to be run.

    ReplyDelete