Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  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. 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.

like image 613
mdma Avatar asked Jun 12 '10 00:06

mdma


People also ask

How do you make a generic type in Java?

To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class. As you can see, all occurrences of Object are replaced by T.

How do you define generic type?

Definition: “A generic type is a generic class or interface that is parameterized over types.” Essentially, generic types allow you to write a general, generic class (or method) that works with different types, allowing for code re-use.

Which character is used for generic type?

The question mark ( ? ) wildcard character can be used to represent an unknown type using generic code. Wildcards can be used with parameters, fields, local variables, and return types.


1 Answers

It is possible to find the actual type argument of the Dao sub-interface (CustomerDAO), by invoking the following method:

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.

In my implementation, a DaoFactory performs this call and uses the domainClass as a constructor argument for the DaoInvocationHandler.

like image 140
Christian Semrau Avatar answered Oct 21 '22 22:10

Christian Semrau