简体   繁体   English

使注释可用于泛型类型

[英]Annotation to make available generic type

Given an generic interface like 给定一个通用接口

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

I'd like to create a subinterface that specifies the type parameter: 我想创建一个指定type参数的子接口:

  interface CustomerDAO extends DomainObjectDAO<Customer> 
  {
       // customer-specific queries - incidental.
  }

The implementation needs to know the actual template parameter type, but of course type erasure means isn't available at runtime. 实现需要知道实际的模板参数类型,但是当然类型擦除手段在运行时不可用。 Is there some annotation that I could include to declare the interface type? 我可以包含一些注释来声明接口类型吗? Something like 就像是

  @GenericParameter(Customer.class)
  interface CustomerDAO extends DomainObjectDAO<Customer> 
  {
  }

The implementation could then fetch this annotation from the interface and use it as a substitute for runtime generic type access. 然后,实现可以从接口获取此批注,并将其用作运行时泛型类型访问的替代。

Some background: 一些背景:

This interface is implemented using JDK dynamic proxies as outlined here . 此接口使用JDK动态代理为实现概述这里 The non-generic version of this interface has been working well, but it would be nicer to use generics and not have to create the methods in a subinterface just to specify the domain object type. 这个接口的非泛型版本运行良好,但使用泛型更好,而不必在子接口中创建方法只是为了指定域对象类型。 Generics and proxies take care of most things, but the actual type is needed at runtime to implement the newInstance method, amongst others. 泛型和代理处理大多数事情,但在运行时需要实际类型来实现newInstance方法等。

It is possible to find the actual type argument of the Dao sub-interface (CustomerDAO), by invoking the following method: 通过调用以下方法,可以找到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];
}

When you call it like 当你称之为

Class<?> domainClass = getDomainClass(daoInterface);

with daoInterface == CustomerDAO.class , then you will get domainClass == Customer.class . 使用daoInterface == CustomerDAO.class ,您将获得domainClass == Customer.class

In my implementation, a DaoFactory performs this call and uses the domainClass as a constructor argument for the DaoInvocationHandler . 在我的实现,一个DaoFactory执行此调用和使用domainClass作为一个构造函数参数DaoInvocationHandler

The implementation needs to know the actual template parameter type. 实现需要知道实际的模板参数类型。

Surely, any implementation of CustomerDao implicitly knows that the type parameter is Customer . 当然, CustomerDao任何实现都隐含地知道 type参数是Customer It is implementing DomainObjectDAO<Customer> not DomainObjectDAO<T> . 它正在实现DomainObjectDAO<Customer>而不是DomainObjectDAO<T>

Problems are only going to arise if the CustomerDao class extends a generic abstract class, and that generic abstract class needs to know the actual type of T . 如果CustomerDao类扩展了泛型抽象类,并且该泛型抽象类需要知道T的实际类型,那么问题才会出现。 But you can deal with that by passing the Class object for T (in this case Customer.class ) to the superclass as a constructor argument. 但是你可以通过将T的Class对象(在本例中为Customer.class )作为构造函数参数传递给超类来处理它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM