枚举方法的通用返回类型

时间:2014-01-26 15:11:06

标签: java generics enums propertychanged

情境: May Field是我想要观察的Model的属性(类似于PropertyChangeListener)。字段定义为Enum。我想打电话

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

观察者的类型(“Something”)取决于Field,我想强制类型安全。例如,Field.FIRST_NAME将采用FieldObserver< String>

第一种(工作)方法: 我已经可以通过将Field定义为具有公共静态最终字段而不是枚举的泛型类来实现它。所以我有一个Field,我可以使用它来强制类型安全,如下所示:

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

使用Observable<E>中的方法:void addObserver(FieldObserver<? super E> observer)

现在,以下行导致编译时错误,这就是我想要的

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

第二种(尚未开始)方法: 我现在正在尝试使用枚举类实现相同的行为。我的一个方法是:

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();
 }

尝试添加任何类型的FieldObserver(也是正确的)会给我一个编译时错误,如下所示:

  

无法应用Observable中的addObserver(enumer.FieldObserver&lt; capture&lt;?&gt;&gt;)   to(enumer.FieldObserver&lt; java.lang.String&gt;)

有人能告诉我如何让enum-approach工作吗?此外,如果有人对这些方法有更好的解决方案或担忧,我会很感激听到它。

1 个答案:

答案 0 :(得分:3)

不幸的是enum不能是通用的。这是因为enum是一个扩展Enum的普通类,即它的定义如下:

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

因此应用程序员无法在此类中添加更多通用参数。

我建议你做以下工作:

  1. 使您的方法通用,即。将其enum级别定义为public <T> getField(Class<T> type)。为每个枚举成员重写此方法。然后,您可以在方法的任何调用中提供类型。
  2. 不要使用枚举执行此任务。使用公共静态成员和私有构造函数创建普通类。如果您想要类似枚举的行为,请实现您自己的静态values()valueOf()