Android Jelly Bean上的Class.getAnnotations中不会忽略未知的注释

zas*_*nyy 6 java android annotations

问题

根据JSR-175 java规范,如果注释在运行时不可用,则应该默默忽略它.但在Android API 15-16调用getDeclaredAnnotations()导致NoClassDefFoundError异常.在API 17+上,它无一例外地按预期工作.

请查看下面的示例项目了解详情

你会建议什么解决方法?你知道相关的Android bug报告吗?我找不到一个.

我们有一个带@Nullable注释的示例类:

public class SampleClass {
   @Nullable
   private String _content;
}
Run Code Online (Sandbox Code Playgroud)

@Nullable 在构建过程中可用,但是我们将它从apk中排除(切割方法计数),在我们这样做的例子中:

configurations {
   provided
}

android.applicationVariants.all {
   variant -> variant.javaCompile.classpath += configurations.provided
}

dependencies {
   provided group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2'
}
Run Code Online (Sandbox Code Playgroud)

MainActivity我们尝试从该_content字段获取所有注释:

Class clazz = SampleClass.class;
Field[] fields = clazz.getDeclaredFields();
Field field = clazz.getDeclaredField("_content"); 
Annotation[] annotations = field.getDeclaredAnnotations(); // this line is throwing exception on API 15-16
Run Code Online (Sandbox Code Playgroud)

因此,我们在Android API 15-16上获得和例外:

11-24 17:06:49.874 2146-2146/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 java.lang.NoClassDefFoundError: javax/annotation/Nullable
                                                     at java.lang.reflect.Field.getDeclaredAnnotations(Native Method)
                                                     at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:204)
                                                     at im.getsocial.checkannotation.MainActivity.checkReflection(MainActivity.java:26)
                                                     at im.getsocial.checkannotation.MainActivity.onCreate(MainActivity.java:15)
                                                     at android.app.Activity.performCreate(Activity.java:5008)
                                                     ...
                                                  Caused by: java.lang.ClassNotFoundException: javax.annotation.Nullable
                                                     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
                                                     at java.lang.reflect.Field.getDeclaredAnnotations(Native Method) 
                                                     at java.lang.reflect.Field.getDeclaredAnnotations(Field.java:204) 
                                                     at im.getsocial.checkannotation.MainActivity.checkReflection(MainActivity.java:26) 
                                                     at im.getsocial.checkannotation.MainActivity.onCreate(MainActivity.java:15) 
                                                     at android.app.Activity.performCreate(Activity.java:5008) 
                                                     ...
Run Code Online (Sandbox Code Playgroud)

完整的示例项目可在此处获取:http://take.ms/Li3NF

有趣的是,Java 5报告了类似的问题:http://bugs.java.com/view_bug.do?video_id = 6322301

更新

  • 1月27日:简化示例和修复的编译错误