The code below is a simplified version of the pattern my project is using. The standard pattern we use is to have a Writer for each object type. For the subtypes of one abstract type (in this example Animal), I’d like an enum to serve as a lookup for the correct writer.
abstract class Writer<T> {
abstract void write(T value);
}
abstract class Animal {
abstract AnimalType getType();
}
class Cat extends Animal {
AnimalType getType() { return AnimalType.CAT; }
}
class CatWriter extends Writer<Cat> {
void write(Cat value) { }
}
// The AnimalType stores a reference to the correct writer for the Animal subclass
enum AnimalType {
CAT(new CatWriter());
Writer<? extends Animal> writer;
Writer writerThatWorksWithWarning;
Writer<Animal> writerThatWorksButCantBeAssigned;
AnimalType(Writer<? extends Animal> writer) {
this.writerThatWorksWithWarning = writer;
this.writer = writer;
// ERROR: Incompatible Types
this.writerThatWorksButCantBeAssigned = writer;
}
}
Sample use case:
class Test {
public static void main(String... args) {
Animal value = new Cat();
// ERROR: write (capture<? extends Animal) in Writer cannot be applied to (Animal)
value.getType().writer.write(value);
// WARNING: Unchecked call
value.getType().writerThatWorksWithWarning.write(value);
// This line works fine here - but can't be assigned above
value.getType().writerThatWorksButCantBeAssigned.write(value);
}
}
I think that my problem is similar to the problem in this question: Java Generics with wildcard, however I can’t tell how to solve it.
I’ve put the inline errors and warnings I get in the comments.
Any ideas?
Try this instead,
Moreover, I am not sure what are you up to. But I believe that Visitor pattern will come handy in this case.
Problem with the above solution, the code below will break the thing.