Android注解解析与使用

本文深入解析Java注解的原理和应用,涵盖元注解、常用注解及自定义注解的实现,帮助开发者掌握注解在代码元数据管理、代码生成和运行时元数据访问中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注解

​ Annotation:Java提供的一种元程序中的元素关联任何信息或者任何元数据(metadata)的途径和方法
基本规则:Annotation(注解)不能影响程序代码的执行,无论增加,删除注解,代码都始终如一的执行

元数据(metadata)

​ 1、以标签的形式存在于Java代码中
2、描述的信息是类型安全的
3、需要编译器之外的工具额外的处理用来生成其他的程序部件
4、可以存在于Java源代码级别,也可以存在于Java代码编译之后的class文件内部

元注解

用来定义其他注解的注解,四种元注解:@Retention、 @Target、@Inherited、@Documented。

@Target
表示使用范围,如:@Target(ElementType.METHOD),参数是一个ElementType类型的数组

参数说明
TYPE类,接口(包括注释类型)或enum声明
FIELD域声明(包括enum实例)
METHOD方法声明
PARAMETER参数声明
CONSTRUCTOR构造器的声明
LOCAL_VARIABLE局部变量声明
ANNOTATION_TYPE注解类型声明
PACKAGE包声明
TYPE_PARAMETER输入参数声明
TYPE_USE使用类型声明

@Retention
表示在什么级别保存注解信息,如:@Retention(RetentionPolicy.SOURCE)

参数说明
SOURCE注解将被编译器丢弃
CLASS注解在class文件中谁用,但会被JVM抛弃
RUNTIME在运行期也保留注解信息,可通过发射机制读取注解信息

@Document
标记的注解可以被javadoc此类的工具文档化
@inherited
表明我们标记的注解是被继承的。如果一个父类使用了@Inherited修饰的注解,则允许子类继承该父类的注解。

常用Java注解

@Override
子类对父类方法的重写所带的注解
@Deprecated
表示已经过时,不建议使用,但是依然可以使用
@SuppressWarnings
用来抑制编译时的警告信息,如:@SuppressWarnings(“all”)

参数说明
deprecation过滤使用了过时的类或方法的警告
unchecked过滤执行了未检查的转换警告
fallthrough过滤switch语句发生case穿透的警告
path过滤类路径,源文件路径等路径不存在的警告
serial过滤可序列化类上缺少serialVersionUID定义时的警告
finally过滤任何finally子句不能完成时的警告
all过滤所有情况的警告

常用Android注解

@NonNull
声明方法的参数不能为空
@Nullable
表示一个方法的参数或者返回值可以是Null的
@CallSuper
重写的方法必须要调用super方法
@RequiresPermission
辅助发现需要申请的权限
@CheckResult
用来注解方法,如果一个方法得到了结果,却没有使用这个结果,就会有错误出现
@Keep
不混淆

Resource Type(资源类型)

​ 指定传入参数的类型,通常用于传入资源的方法中,资源注解如下:AnimRes,AnimatorRes,AnyRes,ArrayRes,AttrRes,BoolRes,ColorRes,DimenRes,DrawableRes,FractionRes,IdRes,IntegerRes,InterpolatorRes,LayoutRes,MenuRes,PluralsRes,RawRes,StringRes,StyleRes,StyleableRes,TransitionRes,XmlRes
@ColorInt
限定颜色资源id

Threading相关

@UiThread
通常可以等同于主线程,标注方法需要在UIThread执行
@MainThread
主线程,经常启动后创建的第一个线程
@WorkerThread
工作者线程,一般为一些后台的线程,如AsyncTask的doInBackground()
@BinderThread
注解方法必须要在BinderThread线程中执行,使用较少

自定义注解

案例一

1 //自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CalculateMethodRunningTime {
	//String为返回值类型,methodName为方法名,default表示使用注解时未指定参数
    String methodName() default "no method to set";
}
2 //构建注解功能
public static void getClassInfo(String className) {
	try {
		Class c = Class.forName(className);
		//获取所有公共的方法
		Method[] methods = c.getMethods();
		for(Method m : methods) {
			Class<CalculateMethodRunningTime> ctClass = CalculateMethodRunningTime.class;
			if(m.isAnnotationPresent(ctClass)){
				CalculateMethodRunningTime anno = m.getAnnotation(ctClass);
				//当前方法包含查询时间的注解时
				if(anno != null){
					long beginTime = System.currentTimeMillis();
					m.invoke(c.newInstance(),null);
					long endTime = System.currentTimeMillis();
					long time = endTime - beginTime;
					Log.i("Tag",anno.methodName()+"方法执行所需要时间:" + time + "ms");
...
3 //使用注解,注意getClassInfo传入的是自定义注解的全包名
AnnotationUtils.getClassInfo("demo.com.mycamear.ActivityAnnotattion");
method1();

案例二

//自定义注解
@Documented
//适用时机
@Retention(RetentionPolicy.RUNTIME)
//适用范围
@Target({ElementType.FIELD,ElementType.METHOD})
@interface MyTarget{
    String name();
    int age();
    int getScore() default 0;
}
//应用于Bean类
public class MyStudent{
    //同时设置自定义注解的三个属性
    @MyTarget(name = "lishan", age = 12,getScore = 111)
    public String name;
    //值设置自定义注解的两个属性,因为getScore属性有默认值,可以不设置
    @MyTarget(age = 14, name = "zhansan")
    public int age;
    //将自定义注解设置在方法上
    @MyTarget(age = 13,name = "wangwu")
    public void method(){}
}
//使用
AnnoationUtils.getInfo(MyStudent.class);
//相关引用
public class AnnoationUtils{
    private static final String TAG = "AnnoationUtils";
    public static void getInfo(Class<?> beanClazz){
        //获取Bean类所有公共成员变量
        Field[] fields = beanClazz.getDeclaredFields();
        //遍历Bean类所有公共成员变量
        for (Field field : fields){
            //判断成员变量的注解
            if (field.isAnnotationPresent(MyTarget.class)){
                //获取成员变量的注解
                MyTarget myTarget = field.getAnnotation(MyTarget.class);
                Log.e(TAG, myTarget.name());
            }
        }
        Method[] methods = beanClazz.getDeclaredMethods();
        for (Method method : methods){
            if (method.isAnnotationPresent(MyTarget.class)){
                MyTarget mytarget = method.getAnnotation(MyTarget.class){
                    mytarget.getScore()
}}}}}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值