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
方法等.
通过调用以下方法,可以找到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
.