【问题标题】:Annotation is not visible on some compilers注解在某些编译器上不可见
【发布时间】:2014-08-10 16:17:20
【问题描述】:

我有一个很有趣的问题。 我已经定义了注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnot {

}

我有:

public interface F<T>{
  public void onFinish(T param);
}

public abstract class Foo<T> implements F<T>{
}

还有:

public class Bar extends Foo<Drawable>{
  @Override
  @MyAnnot  
  public void onFinish(Drawable d){
    // ...
  }
}

还有:

public class FooBar extends Bar{

  @Override
  @MyAnnot  
  public void onFinish(Drawable d){
    // ...
  }
}

在 Foo 中我添加的一种方法中:

Method method = this.getClass().getMethod("onFinish", Object.class);
if (method.isAnnotationPresent( MyAnnot.class )){
  //Do sth
}

我在 android 项目中使用它,在我的一台计算机上它工作正常,但第二个 isAnnotationPresent 总是返回 false。在这两种情况下,应用程序都是由 IntelliJ Idea 在同一部手机上运行的。

另外,如果我使用this.getClass().getMethod("onFinish", Drawable.class);,它适用于所有计算机。

【问题讨论】:

  • 我会说这更多地指向类路径的问题,而不是编译器本身的问题。
  • 嘿,我忘记了界面,不应该像我的项目中那样。公共类 Bar 和 FooBar 中的 @Aubin 不能有抽象方法,因为它们是已实现的类。 :)
  • 我尝试编译你的代码。我有一些解释...等一下
  • 我哪儿也不去,在我 GF 的电脑上安装 IDE 来检查一下。

标签: java android annotations


【解决方案1】:

这是一种使用反射找到正确参数以提供给getMethod( name, type ) 的方法。

代码:

package so;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public abstract class Foo<T> implements F<T> {

   public static Class<?> getParameterizedType( Class<?> clazz ) {
      Type t = clazz.getGenericSuperclass();
      while( t != Object.class ) {
         if( t instanceof ParameterizedType ) {
            final Type[] actualTypeArguments =
               ((ParameterizedType)t).getActualTypeArguments();
            for( final Type arg : actualTypeArguments ) {
               return (Class<?>)arg;
            }
         }
         t = ((Class<?>)t).getGenericSuperclass();
      }
      throw new IllegalStateException();
   }

   public static void main( String args[] ) throws Exception {
      final Object fooBar = new FooBar();
      final Class<?> clazz = fooBar.getClass();
      final Class<?> finishArgType = getParameterizedType( clazz );
      System.err.println( "finishArgType = " + finishArgType );
      final Method mth = clazz.getMethod( "onFinish", finishArgType );
      if( mth.isAnnotationPresent( MyAnnot.class )) {
         System.err.println( "Yessssssss!" );
      }
   }
}

输出:

finishArgType = class so.Drawable
Yessssssss!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 2021-07-22
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    相关资源
    最近更新 更多