使注释可用于泛型类型

mdm*_*dma 11 java generics annotations

给定一个通用接口

interface DomainObjectDAO<T>
{
   T newInstance();
   add(T t);
   remove(T t);
   T findById(int id);
   // etc...    
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个指定type参数的子接口:

  interface CustomerDAO extends DomainObjectDAO<Customer> 
  {
       // customer-specific queries - incidental.
  }
Run Code Online (Sandbox Code Playgroud)

实现需要知道实际的模板参数类型,但是当然类型擦除手段在运行时不可用.我可以包含一些注释来声明接口类型吗?就像是

  @GenericParameter(Customer.class)
  interface CustomerDAO extends DomainObjectDAO<Customer> 
  {
  }
Run Code Online (Sandbox Code Playgroud)

然后,实现可以从接口获取此批注,并将其用作运行时泛型类型访问的替代.

一些背景:

此接口使用JDK动态代理为实现概述这里.这个接口的非泛型版本运行良好,但使用泛型更好,而不必在子接口中创建方法只是为了指定域对象类型.泛型和代理处理大多数事情,但在运行时需要实际类型来实现该newInstance方法等.

Chr*_*rau 7

通过调用以下方法,可以找到Dao子接口(CustomerDAO)的实际类型参数:

import java.lang.reflect.ParameterizedType;

public static Class<?> getDomainClass(final Class<?> daoInterface) {
    ParameterizedType type = (ParameterizedType) daoInterface.getGenericInterfaces()[0];
    return (Class<?>) type.getActualTypeArguments()[0];
}
Run Code Online (Sandbox Code Playgroud)

当你称之为

Class<?> domainClass = getDomainClass(daoInterface);
Run Code Online (Sandbox Code Playgroud)

daoInterface == CustomerDAO.class,然后你会得到domainClass == Customer.class.

在我的实现中,a DaoFactory执行此调用并使用domainClass作为构造函数的参数DaoInvocationHandler.