2

Is there something that I can do to simulate "on created" event?

I have a base class which other people can extend, and currently I have an init() that will initialize the instance, but it should be called only after the constructor stack completes.

If I call init() in the base class' constructor, then I might potentially initialize wrongly, because the subclass' constructor has not finished executing. The subclass can initialize values of some of the protected fields, which would have an impact on how init() initializes the instance.

My current approach is to make init() protected final, and asks that subclasses must call it at the end of their constructor. This approach works, but only provided if subclasses really do follow the instruction.

Edit

I thought I would give some extra information. This is part of a JavaFX project/custom API. So I had tried using Platform.runLater(() -> init()), which was a major mistake. Platform.runLater() would only run after the whole execution stack completes, which causes the usage of uninitialized instance in this case:

Foo instance = new Foo();
instance.doSomething();
Community
  • 1
  • 1
Jai
  • 8,165
  • 2
  • 21
  • 52
  • 1
    asking implmentor to do some specific things doesn't sound good. i don't think there is a solution in this case. have you considered refactoring the code? – Jason Hu Nov 06 '17 at 01:26
  • do you have to call init() after base class constructor or child class constructor? – Fermat's Little Student Nov 06 '17 at 01:26
  • @Will After the outer most subclass' constructor. So if someone decides to make an abstract class that extends my class, then init() should not be called there, but in the concrete class' constructor. – Jai Nov 06 '17 at 01:32

1 Answers1

0

There is no easy way to force a method call in the end of subclass constructor. This may be doable via annotation processor, which let you modify source code at precompile time. But it will be complicated. I think instead of subclassing, your goal can be better achieved using factory pattern instead.

You can define a few setters to let users initialize your fields, then call init in the end of your factory method.

Fermat's Little Student
  • 5,549
  • 7
  • 49
  • 70