簡體   English   中英

Java、泛型和類<Generic>問題

[英]Java, Generics and Classe<Generic> problems

這是我模型的父級:

abstract public class ApiModel {
    // Problem 1
    public static ExpressionList<Model> 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() {
            // Problem 2
        ExpressionList<T> list = T.find();
        return ok(Json.toJson(list.orderBy("name"), 10));
    }
    
    public Result create() {
        return update(null);
    }
    
    public Result details(Long id) {
            // Problem 3
        T model = T.findById(id);
        
        // ...
        return ok(result);
    }
    
    public Result update(Long id) {
            // Problem 4
        Form<T> form = form(T.class).bindFromRequest();

            T model = form.get();

            // Problem 5
            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. 我需要find()來返回ExpressionList<T extends Model> ,但如果我把這個,我有一個錯誤。
  2. Pb1 使這個錯誤出現,它說“類型不匹配:無法從 ExpressionList 轉換為 ExpressionList”。 我想通過修復 1., 2. 也將被修復。
  3. 這個很奇怪,它返回“綁定不匹配:ApiModel 類型的泛型方法 findById(Long) 不適用於參數 (Long)。推斷的類型 T&Model 不是有界參數的有效替代品”
  4. 當然我不能使用這個.class 但是我該怎么辦呢?
  5. 由於模型使用注釋來擁有@Entity ,我不能在這里使用它,它不被識別:/

我認為一切都是相關的。 也許我的代碼設計得很差?

這就是這種結構的原因。 我正在使用 PlayFramework(具有靜態控制器)並且我喜歡進行繼承以及通用模型。 但是為此,我需要實例而不是靜態引用,因此public final static AController rest 但是,我無法訪問模型的靜態上下文( find & findById )。 所以我做了 ApiModel。 但這也無濟於事。

如果您重寫一個小ApiController則不需要ApiModel類:

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

}

我不知道你為什么需要ApiModel那些靜態方法。

您應該能夠為ApiController賦予T Class

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

從我的角度來看,這樣做應該是一個壞主意。 你可以在play中使用普通的方法,你只需要在路由列表中以@開頭的方法引用。

所以,如果你有這樣的控制器:

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

您可以在路由器中這樣使用:

GET         /           @controllers.MyController.index()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM