在Class,Method,Field,Constructor中有获取/判断注解存在的方法 常用的API: Annotation getAnnotation(Class annotationClass):判断当前类、方法、字段上是否拥有指定的注解,若有,则返回当前对象,若没有返回null; Annotation[] getAnnotations():返回此元素上存在的所有注释。
boolean isAnnotationPresent(Class annotationClass):如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
注解类:
//定义注解 @Target(ElementType.TYPE)//只能修饰类、接口(包括注释类型)或枚举声明 @Retention(RetentionPolicy.RUNTIME)//该注解可以存在源文件,字节码,JVM中。 public @interface INFO { //注解是特殊的接口,接口中有抽象方法,在注解八抽象方法称为属性 String username(); int age() default 20;//default是设置默认值 String[] hobby(); Gender sex() default Gender.NONE; } Gender需要设置成public: /** * Created by Layne_Yao on 2017-8-5 上午11:11:03. * :http://blog.csdn.net/Jsagacity */ public enum Gender{ BOY,GIRL,NONE; } 赋予特殊功能得类: /** * Created by Layne_Yao on 2017-8-5 上午9:51:42. * :http://blog.csdn.net/Jsagacity */ // 被贴程序元素 @INFO(username = "Layne", age = 18, sex = Gender.BOY, hobby = { "Java", "Android", "C++" }) class User { @Deprecated public void doWork() { } } // 赋予注解特殊功能得 public class AnnotationDemo1 { public static void main(String[] args) throws Exception { // 获取Person类上的VIP注解中的信息 Class cls = User.class; // 获取Person类上所有的注解 Annotation[] as = cls.getAnnotations(); // 判断Person类上是否有VIP注解 boolean isPresent = cls.isAnnotationPresent(INFO.class); if (isPresent) { // 取出Person类上的注解 Annotation a = cls.getAnnotation(INFO.class); // 获取VIP注解中的属性值(调用VIP的抽象方法) INFO vip = (INFO) a; System.out.println(vip.username()); System.out.println(vip.age()); System.out.println(vip.sex()); } // 需求:获取doWork方法上的Deprecated注解 // 1:获取doWork方法所在类的字节码文件 Class doWorkCls = User.class; // 2:获取doWork方法的Method对象 Method m = doWorkCls.getMethod("doWork"); System.out.println(m); // 3:获取当前方法上的注解 Deprecated depre = m.getAnnotation(Deprecated.class); System.out.println(depre); } } 运行结果:
上面程序并没有赋予注解功能。
接下来新建一个Android项目,布局文件里面添加两个控件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.annomationdemo.MainActivity" > <TextView android:id="@+id/tv_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="180dp" android:text="@string/hello_world" /> <Button android:id="@+id/bt_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="Button" /> </RelativeLayout> 新建一个注解类: import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface getViewTo { int value() default -1; } MainActivity.java中: public class MainActivity extends ActionBarActivity { @getViewTo(R.id.tv_show) private TextView tv_show; @getViewTo(R.id.bt_show) private Button bt_show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //通过注解生成View getAllAnnomationView(); bt_show.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { tv_show.setText("注解获取成功"); } }); } /** * 解析注解,获取控件 */ private void getAllAnnomationView() { //获取成员变量 Field[] fields = this.getClass().getDeclaredFields(); for (Field field : fields) { try { //判断注解是否为空 if(field.getAnnotations()!=null){ //确定注解类型 if(field.isAnnotationPresent(getViewTo.class)){ //允许修改反射属性 field.setAccessible(true); getViewTo getViewTo = field.getAnnotation(getViewTo.class); //通过findViewById将注解的id,找到View并注入成员变量中 field.set(this, findViewById(getViewTo.value())); } } } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } } } } 这里就不演示运行结果了,大家运行过后可能有点感觉像ButterKnife,不过ButterKnife比这个强大多了。