Java,Generics和Classe <generic> problems </generic>

时间:2012-08-11 14:29:13

标签: java generics playframework ebean

代码更明确为千言万语:

这是我模特的父母:

abstract public class ApiModel extends Model {
    public static <T extends Model> ExpressionList<T> find() {
        return null;
    }

    public static <T extends Model> T findById(Long id) {
        return null;
    }
}

模特:

public class MyModel extends ApiModel {

    private static Model.Finder<Long,MyModel> find = new Model.Finder(Long.class, MyModel.class);

    public static ExpressionList<MyModel> find() {
        return find.where();
    }

    public static MyModel findById(Long id) {
        return find.byId(id);
    }
}

父母的控制者:

public class ApiController<T extends ApiModel> extends Controller {
    public Result list() {
        ExpressionList<T> list = T.find();
        return ok(Json.toJson(list.orderBy("name"), 10));
    }

    public Result create() {
        return update(null);
    }

    public Result details(Long id) {
        T model = T.findById(id);

        // ...
        return ok(result);
    }

    public Result update(Long id) {
            // Problem 1
        Form<T> form = form(T.class).bindFromRequest();

            T model = form.get();

            T.save();

        // ...
        return ok(result);
    }

    public Result delete(Long id) {
        // ...
        return ok(result);
    }
}

控制器

public class AController extends ApiController<MyModel> {
    public final static AController rest = new AController();

    private AController() {}
}

(更新:除了这个问题之外,所有问题都已解决)

我面临的问题:

  1. 当然我不能使用这个.class。但那我该怎么办?
  2. 也许我的代码设计很差?

    这就是这种结构的原因: 我正在使用PlayFramework(有静态控制器),我喜欢做继承,因此也喜欢通用模型。但为此,我需要实例而不是静态引用,因此public final static AController rest。但是,我无法访问模型的静态上下文(find&amp; findById)。所以我做了ApiModel。但它也无济于事:/

    非常感谢你的帮助。

3 个答案:

答案 0 :(得分:2)

如果您重写一点ApiModel,则不需要ApiController课程:

public class ApiController<T extends Model> extends Controller {

    private Model.Finder<Long,T> finder;

    private final Class<T> modelClass;

    public ApiController(Class<T> modelClass) {
        this.modelClass = modelClass;
        finder = new Model.Finder(Long.class, modelClass);
    }

    public Result list() {
        ExpressionList<T> list = finder.where();
        return ok(Json.toJson(list.orderBy("name"), 10));
    }

    public Result details(Long id) {
        T model = finder.findById(id);

        // ...
        return ok(result);
    }

    public Result update(Long id) {
        // Problem 1
        Form<T> form = form(modelClass).bindFromRequest();

            T model = form.get();

            T.save();

        // ...
        return ok(result);
    }

    ...
}

public class AController extends ApiController<MyModel> {
    public final static AController rest = new AController();

    private AController() {
        super(MyModel.class);
    }

}

答案 1 :(得分:0)

我不知道你为什么需要ApiModel中的静态方法。

您应该能够ApiControllerClass T赋予public class ApiController<T extends ApiModel> extends Controller { private final Class<T> tClass; ApiController(Class<T> tClass) { this.tClass = tClass; } public class AController extends ApiController<MyModel> { .... private AController() { super(MyModel.class); }

{{1}}

答案 2 :(得分:0)

从我的观点来看,做到这一点应该是一个坏主意。您可以在游戏中使用常规方法,只需在路径列表中引用方法,并在开头使用@

所以,如果你有这样的控制器:

public class MyController extends Controller {
    public Result index() {
        return TODO;
    }
}

您可以在路由器中使用这样的内容:

GET         /           @controllers.MyController.index()