2015-11-24 6 views
1

У меня есть интерфейс, содержащего метод принимающего объект типа java.lang.ClassУнифицированное использование javax.lang.model.type.TypeMirror и java.lang.Class

public interface TypeReviewer { 
    public int evaluate(Class<?> type); 

    ... 
} 

Теперь я хочу, чтобы поддержать использование объектов этого интерфейса в обработчике аннотаций. Но, так как некоторые классы не могли быть составлены во время обработки аннотаций, мне кажется, что мне нужно добавить метод

public int evaluate(TypeMirror type) 

к интерфейсу. (Возможно, мне придется добавить параметр типа javax.lang.model.util.Types, но это не имеет значения для предстоящего вопроса)

Для меня нет смысла добавлять этот метод в интерфейс как он должен вычислять точно такое же значение для javax.lang.model.type.TypeMirror, а TypeMirror в основном представляет класс. Это также возможный пункт отказа в качестве программиста, реализация которого в этом классе может привести к различным результатам в этих методах точно для одного и того же типа.

Это приводит меня к моему вопросу: Что я могу сделать, чтобы избежать такой избыточной реализации для обработки аннотаций и любого другого поля метапрограмм?

+0

Как вы используете этот класс в своем обработчике аннотаций? –

+0

Я ищу TypeElements с определенной аннотацией, а затем я использую метод asType() аннотированного типа для получения объекта TypeMirror. Реализация TypeReviewer меняется, поскольку я создаю эти объекты через некоторые отражения. – narranoid

+0

Итак, интерфейс предназначен исключительно для использования в обработчике аннотаций? И пытаетесь ли вы выполнить требование, чтобы тип, который представляет TypeMirror, должен быть частью контракта с интерфейсом? –

ответ

1

Во время выполнения у вас не будет доступа к экземплярам TypeMirror. Во время компиляции у вас не будет доступа ко всем экземплярам класса. Поэтому нет единого унифицированного варианта. Лучшее решение, которое я мог бы подумать (что может быть уместно в зависимости от сложности вашего приложения), заключается в создании собственного упрощенного типа API. Вот приблизительный эскиз:

public interface MyType { 

    public boolean isSubclassOf(MyType otherType); 

} 

public class MyTypeClassImpl implements MyType { 

    private Class<?> clazz; 

    public MyTypeClassImpl(Class<?> clazz) { 
     this.clazz = clazz; 
    } 

    public boolean isSubclassOf(MyType otherType) { 
     if(otherType instanceof MyTypeClassImpl) { 
      return clazz.isAssignableFrom(((MyTypeClassImpl)otherType).clazz); 
     } else { 
      throw new RuntimeException("TypeMirror encountered in non-annotation-processing environment"); 
     } 
    } 

} 

//Similar implementation for type mirrors 

public interface TypeFactory { 

    public MyType fromJavaType(Object type); 

} 

public class AnnotationProcessorTypeFactory { 

    private ProcessingEnvironment processingEnv; 

    public MyType fromJavaType(Object type) { 
     if(type instanceof TypeMirror) { 
      return MyTypeMirrorImpl((TypeMirror)type); 
     } else if (type instanceof Class<?>) { 
      return MyTypeMirrorImpl(convertToTypeMirror((Class<?>)type)); 
     } 
    } 

    private TypeMirror convertToTypeMirror(Class<?> clazz) { 
     return processingEnv.getElementUtils().getTypeElement(clazz.getCanonincalName()); 
    } 

} 

public class RuntimeTypeFactory implements TypeFactory { 

    public MyType fromJavaType(Object type) { 
     if(!(type instanceof Class<?>)) { 
      throw new RuntimeException("Illegal use of non-class type in runtime environment"); 
     } 
     return new MyTypeClassImpl((Class<?>)type); 
    } 

} 
+0

для кросс-использования в мета-полях и средах времени выполнения, особенно в моих случаях, это, кажется, решение. Благодаря! – narranoid

2

В настоящее время отсутствует единая абстракция по мольным моделям.

Был/is JEP 119 ("javax.lang.model Implementation Backed Core Reflection"), который, к сожалению, еще не был включен в JDK. Этот blog post от Joe Darcy светит на него, и там также была прототипная реализация где-то в репозитории OpenJDK, но я больше не могу ее найти.

+0

Согласно http://mail.openjdk.java.net/pipermail/jdk8-dev/2014-January/003922.html, он не был включен в окончательную версию: «мы * не *, включая код JEP 119, как часть API JDK - он не является Java SE API (в java. * или javax. *) и не является поддерживаемым JDK API (в jdk. * или в другом месте), поддерживающим JDK-интерфейс. Реализация это всего лишь образец доказательной концепции ». –

Смежные вопросы