I have an init method that is used and overridden through out an extensive heirarchy. Each init call however extends on the work that the previous did. So naturally, I would:
@Override public void init() {
super.init();
}
And naturally this would ensure that everything is called and instantiated. What I'm wondering is: Can I create a way to ensure that the super method was called? If all of the init's are not call, there is a break down in the obejct, so I want to throw an exception or an error if somebody forgets to call super
.
TYFT ~Aedon
I frequently like to use this solution. It wont throw a runtime error, but it will show a syntax error:
This is a part of Android support annotations.
Here's one way to raise an exception if a derived class fails to call up to the superclass:
Nowadays you can annotate your method with
@CallSuper
. This will Lint check that any overrides to that method calls super(). Here's an example:In the example above, any methods in descendant classes that override onAfterAttached but do not call super will make Lint raise an error.
Android actually accomplishes this in the
Activity
class. I'm not sure how or whether they had to build support into the runtime for it, but I'd check out the open source code for theActivity
class implementation. Specifically, in any of the lifecycle methods, you have to call the corresponding super class method before you do anything otherwise it throwsSuperNotCalledException
.For instance, in
onCreate()
, the first thing you have to do is callsuper.onCreate()
.I don't know of any way to do this with a method.
However, note that this is exactly how constructors work. Every constructor must, directly or indirectly, call one of its superclass's constructors. This is statically guaranteed.
I note that you are writing an init method. Could you refactor so that your code uses constructors rather than init methods? That would give you this behaviour right out of the gate. Some people (eg me) prefer constructors to init methods anyway, partly for just this reason.
Note that using constructors rather than init methods might not mean using them on the class you're currently looking at - there might be a refactoring which moves the state needing initialisation out into a parallel class hierarchy which can use proper constructors.
Rather than trying to do that -- I don't think it's achievable btw! -- how about a different approach:
Would that work for you?