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: http://stackoverflow.com/questions/1108894/java-generics-problem-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?