为什么这种通用用法在 groovy 中不起作用?

Why doesn't this generic usage work in groovy?

学习 Groovy 和 Grails,我正在尝试通过制作 BaseController 来简化一些控制器。

我定义如下:

class BaseController<T> {

    public def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond T.list(params), model:[instanceCount: T.count()]
    }
}

然后我有以下内容:

class TeamController extends BaseController<Team> {
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    /*
    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond Team.list(params), model:[teamInstanceCount: Team.count()]
    }
    */
}

每次我尝试调用它时,我都会在 T.count() 上收到 MethodMissingException。为什么 Team.count() 有效,但当我尝试使用泛型时 T.count() 失败?

-- 编辑 -- (添加例外) 无方法签名:static java.lang.Object.count() 适用于参数类型:() 值:[]

T 是一种类型。所以这不会像您期望的那样工作。你必须持有一个具体的class(见Calling a static method using generic type)。

所以在你的情况下,最简单的方法是也传递真实的 class。例如:

class A<T> {
    private Class<T> clazz
    A(Class<T> clazz) { this.clazz = clazz }
    String getT() { T.getClass().toString() }
    // wrong! String getX() { T.x }
    String getX() { clazz.x }
}

class B {
    static String getX() { return "x marks the place" }
}

class C extends A<B> {
    C() { super(B) }
}

assert new C().x=="x marks the place"