浅谈关于Java的注解使用

定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
作用分类:
①编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
② 代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
③编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】

一、自定义注解
注解的声明跟接口的声明类似,不同的是注解需要在interface前添加@,如下代码:

package com.ishow.xutils;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by huangxuanheng on 2015/9/20
 */
@Retention(RetentionPolicy.RUNTIME)     //声明该注解是在运行时
@Target(ElementType.FIELD)    //声明注解用于字段的声明
public @interface Inject {   
    int value();    //声明一个int值的属性
    String name();  //声明一个String类型的属性
}

说明:在注解上也可以使用其他注解,自定义的注解的成员可以是基本数据类型,也可以是String 类型、注解类型、枚举类型等。

二、使用反射方式获取注解

package com.ishow.xutils;

import android.app.Activity;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by Administrator on 2015/9/20.
 */
public class XUtils {
    /**
     *为activity相关含有注解Inject的控件属性进行实例化
     * @param handle
     */
    public static void inject(Activity handle)  {
        //获取对象handle的字节码,用于获取对象的相关属性和注解
        Class<Activity> handleClass = (Class<Activity>) handle.getClass();
        Field[] fields = handleClass.getDeclaredFields();
        for(Field field :fields){
            //判断对应注解是否是该属性的注解,如果是,则获取该注解的值,设置给该属性
            if(field.isAnnotationPresent(Inject.class)){
                Inject annotation = field.getAnnotation(Inject.class);
                field.setAccessible(true);
                try {
                    Method findViewById = getDeclaredMethod(handleClass,"findViewById", int.class);
                    findViewById.setAccessible(true);
                    Object obj=findViewById.invoke(handle,annotation.value());
                    field.set(handle,obj);
                } catch (Exception e) {
                    System.out.print(e.getMessage());
                }
            }
        }
    }
    /**
    * 使用递归获取方法对象
    * 根据指定的字节码对象和指定方法名称及该方法对应的参数类型,获取该方法或者父类中的具有名称为name的方法对象
    */
    private static Method getDeclaredMethod(Class<?>handleClass,String name ,Class<?>... parameterTypes){
        Method method=null;
        try {
            method = handleClass.getDeclaredMethod(name, parameterTypes);
            return method;
        } catch (NoSuchMethodException e) {
            return getDeclaredMethod(handleClass.getSuperclass(), name, parameterTypes);
        }
    }
}

三、使用注解

package com.ishow.huangxuanheng;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import com.ishow.xutils.Inject;
import com.ishow.xutils.XUtils;

public class MainActivity extends AppCompatActivity {

    @Inject(R.id.tv)
    private TextView tv;    //为属性tv定义注解
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //通过调用inject方法为属性tv进行findViewById注册
        XUtils.inject(this);
        //注册了tv,就可以直接调用tv对象的所有方法了
        tv.setText("hello android ,i love you!!");
    }
}

本例主要是通过反射,获取到对应activity类中定义的属性Field,再通过判断该属性是否声明有指定的注解,如果有,则通过反射获取activity中的方法findViewById对该属性进行注册到activity中,注册完成后,再调用其相应方法完成相关工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值