質問

Situation: May Field be a property of a Model which I want to observe (something similar to PropertyChangeListener). Field is defined as Enum. I want to call

someModel.getField(Field f).addObserver(FieldObserver<Something> observer)

the Observer's type ("Something") depends on the Field and I want to force typesafety. For example Field.FIRST_NAME would take a FieldObserver< String>.

First (working) approach: I could already reach it by defining Field as generic class with public static final fields, instead of enum. So I have a Field, which I can use to force type safety like this:

public <E> Observable<E> getField(Field<? extends E> f)

with method in Observable<E>: void addObserver(FieldObserver<? super E> observer)

Now the following line causes a compile time error, which is what I want:

someModel.getField(Field.some_STRING_field).addObserver(INTEGERObserver)

Second (not working yet) approach: I am trying now to implement the same behaviour with the enum class. One of my approach is:

public enum Field{
 FIRST_NAME("firstName") {
        @Override
        public Observable<String> getObservable() {
            return new Observable<String>();
        }
    },...

    //every Field must implement:
    public abstract FieldObservable.Observable<?> getObservable();`
 } 

 //getField(Field f) of the Model-class:
 public Observable<?> getField(Field f){
    return f.getObservable();
 }

Trying to add a FieldObserver of any type (also the correct one) gives me a compile time error like this:

addObserver (enumer.FieldObserver< capture< ?>>) in Observable cannot be applied to (enumer.FieldObserver< java.lang.String>)

Can someone tell me how to make the enum-approach work? Also if someone has a better solution or concerns about the approaches, I will be thankful to hear it.

役に立ちましたか?

解決

Unfortunately enums cannot be generic. This is because enum is an ordinary class that extends Enum, i.e. its definition looks like the following:

class MyEnum<E extends Enum<E>> extends Enum<E extends Enum> {}

So application programmer cannot add more generic parameter to this class.

I can suggest you the following work arounds:

  1. Make your method generic, ie. define it in enum level as public <T> getField(Class<T> type). Override this method for each enum member. Then you can supply the type at any call of the method.
  2. Do not use enum for this task. Create ordinary class with public static members and private constructor. if you want enum-like behavior implement your own static values() and valueOf().
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top