阅读泛型类Java的注释

时间:2015-05-29 15:15:31

标签: java generics annotations

我有一个使用Dao类(Dao.java)的想法:

class Dao <Model extends AbstractModel> {
    public String getUrl() {
        return Model.class.getAnnotation(MyPath.class).url();
    }
}

和这样的模型(Account.java):

@MyPath(url = "blabla")
class Account extends AbstractModel {
    ...
}

但问题是在那种情况下,如果我运行

@Test
public void testDaoUrl() {
    Dao<Account> dao = new Dao<Account>();
    dao.getUrl();
}

Model.class似乎是一个AbstractModel而不是一个Account。 是否有任何工作可以从Dao获取MyPath注释(不给它一个Account.class实例)?

提前感谢任何想法!

PS:MyPath-Annotation:

@Retention(RUNTIME)
@Target(TYPE)
@interface MyPath {
    public String url();
}

1 个答案:

答案 0 :(得分:1)

是的,还有另一个解决方案,但它比将Class参数传递给Dao构造函数更容易出错并且更容易出错。

这个技巧被称为type token。我发现它主要用于反序列化库(如GSON或Jackson for JSON)。

class Dao<Model extends AbstractModel> {
    private final Class<?> typeArgument;

    public Dao() {
        Type superclass = getClass().getGenericSuperclass(); 
        ParameterizedType parameterized = (ParameterizedType) superclass;
        // with nested generic types, this becomes a little more complicated
        typeArgument = (Class<?>) parameterized.getActualTypeArguments()[0];
    }

    public String getUrl() {
        return typeArgument.getAnnotation(MyPath.class).url();
    }
}

并像这样使用

new Dao<Account>(){}.getUrl()

因此,在创建Dao实例时,您实际上创建了一个Dao子类实例。这样,实例的参数化子类型为Dao,即。

之类的东西
class AnonymousDao extends Dao<Account> {}

然后可以提取和使用参数化类型。