Reputation: 1489
I have following classes:
public class A extends Exception {
}
public class B extends Email {
}
My goal is to implement some strategy that would be able to work with both those classes like below:
For instance:
public enum Strategy {
ACTION_1 {
@Override
public void handleAction(Class<? extends Exception > parameterThatShouldAcceptOnlyA) {
throw parameterThatShouldAcceptOnlyA;
}
},
ACTION_2 {
@Override
public void handleAction(Class<? extends Email > parameterThatShouldAcceptOnlyB) {
parameterThatShouldAcceptOnlyB.send();
}
};
public abstract void handleAction(Class<?> parameterThatShouldAcceptBoth);
}
This is not compiled through incorrect generic in overriden methods.
Could you please suggest how it would be possible to make this workable?
Upvotes: 0
Views: 110
Reputation: 1845
Hint: It is neither possible to throw a Class
instance nor to invoke other methods than provided by class Class
so at first you need to change your parameter type. This also let you remove the wildcards.
You can define the super class by a generic. Unfortunatelly enums do not support generics. But you can create a generic interface like
interface Handler<T> {
void handleAction(T t);
}
and implement your handler like
class EmailHandler implements Handler<Email> {
void handleAction(Email email) {
email.send();
}
class ExceptionHandler implements Handler<Exception> {
void handleAction(Exception e) {
// Exception is a checked exception
// so we cannot throw it without 'throws' declaration
// but we cannt add 'throws Exception'
if (e instanceof RuntimeException)
throw (RuntimeException) e;
else
throw new RuntimeException("wrapped", e);
}
Upvotes: 1
Reputation: 140633
You better step back here. Your idea simply violates the Liskov Substitution Principle.
Basically you want to restrict a subclass in what can be passed in as argument to a method.
That breaks the whole idea that subclasses can be used in place of their superclass. Because now, all of a sudden, the code that wants to call that method has to check the type of the object it is calling on - to ensure to not call the method with "invalid" parameters.
In other words: take this compiler error as a symptom. Even when you somehow work around the specific issue; as said - you better step back and rethink your whole idea.
Upvotes: 2