java泛型类型结论

时间:2015-10-30 11:34:30

标签: java generics types

查看类结构。我有模特和观点;

plot(sort(table(a)))

我想写一个View with Type safe的结构。

abstract class Model {
}

abstract class View <M extends Model> {
     public M model;
     View(M model) {
        this.model = model;
     }
}

class ButtonModel extends Model {
   public String text;
}
class ButtonView extends View<ButtonModel> {
     public Runnable onClickRunnable;
     ButtonView(ButtonModel model) {
          super(model);
     }

}

为什么我需要将新的ButtonView转换为View?我怎么能把它写得更干净?

4 个答案:

答案 0 :(得分:1)

我认为你过度复杂化了。你不需要在这里使用泛型,只需使用旧的方法重载:

public static ButtonView build (ButtonModel model) {
    return new ButtonView(model);
}

public static SomeOtherView build (SomeOtherModel model) {
    return new SomeOtherView(model);
}

// etc

为每种模型类型编写重载方法与为每种模型类型编写包含instanceof的单个方法没有什么不同。

答案 1 :(得分:0)

如果你不想在你的View<?> createView()类中添加Model抽象方法(似乎你想让你的模型类独立于视图层 - 这是一个好点)那么你将无法使它变得更简单。如果要将类层次结构映射到另一个或多或少并行的类层次结构(在本例中将Model层次结构映射到View层次结构),那么您将需要使用该脏实例和转换的工厂方法。

答案 2 :(得分:0)

  

为什么我需要将新的ButtonView投放到View?我怎么能把它写得更干净?

问题出在您的ButtonView构造函数上,它接受的是ButtonModel,而不是Model。您可以重写此构造函数,但在将来需要的情况下,需要在ButtonView构造函数内部进行相同的转换。

答案 3 :(得分:0)

试试这个:

  public static <V extends View<T>, T extends Model> V build(T model, Class<V> Vclazz) {
        try {
            Constructor<V> constructor = Vclazz.getConstructor(model.getClass());
            return constructor.newInstance();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

这适用于所有视图和模型。请注意,您需要传递具体视图的Class,因为无法在运行时获取它。