Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warn developer to call `super.foo()` in java

Lets say I have these two classes, one extending the other

public class Bar{

    public void foo(){

    }

}

public class FooBar extends Bar {

    @Override
    public void foo(){
        super.foo(); //<-- Line in question
    }

}

What I want to do is warn the user to call the super-class's method foo if they haven't in the override method, is this possible?

Or is there a way to know, using reflection that a method that overrides a method of its super-class calls the original method if I pass on the class type to the super?

for example:

public abstract class Bar{

    public Bar(Class<? extends Bar> cls){
        Object instance = getInstance();
        if (!instance.getClass().equals(cls)) {
            throw new EntityException("The instance given does not match the class given.");
    }
        //Find the method here if it has been overriden then throw an exception
        //If the super method isn't being called in that method
    }

    public abstract Object getInstance();

    public void foo(){

    }

}

public class FooBar extends Bar {

    public FooBar(){
        super(FooBar.class);
    }

    @Override
    public Object getInstance(){
        return this;
    }

    @Override
    public void foo(){
        super.foo();
    }

}

Maybe even an annotation I can put on the super method so it shows that it needs to be called?


EDIT

Note, its not the super class that needs to call the foo method, it would be someone calling the sub class's foo method, for example a database close method

I would even be happy with making the method "un-overrideable" if it came down to it, but would still like to give it a custom message.


Edit 2

This here is what I wanted in a way:

enter image description here

But it would still be nice to have the above, or even give them a custom message to do something else like, Cannot override the final method from Bar, please call it from your implementation of the method instead

like image 854
FabianCook Avatar asked Oct 12 '13 05:10

FabianCook


1 Answers

EDIT: To answer the edited, question, which includes:

I would even be happy with making the method "un-overrideable"

... just make the method final. That will prevent subclasses from overriding it. From section 8.4.3.3 of the JLS:

A method can be declared final to prevent subclasses from overriding or hiding it.

It is a compile-time error to attempt to override or hide a final method.

To answer the original question, consider using the template method pattern instead:

public abstract class Bar {
    public foo() {
        // Do unconditional things...
        ...
        // Now subclass-specific things
        fooImpl();
    }

    protected void fooImpl();
}

public class FooBar extends Bar {
    @Override protected void fooImpl() {
        // ...
    }
} 

That doesn't force subclasses of FooBar to override fooImpl and call super.fooImpl() of course - but FooBar could do this by applying the same pattern again - making its own fooImpl implementation final, and introducing a new protected abstract method.

like image 139
Jon Skeet Avatar answered Nov 02 '22 01:11

Jon Skeet