Annotation

元注解

java中元注解有四个: @Retention @Target @Document @Inherited;

  • @Retention:注解的保留位置         
    • @Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
    • @Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
    • @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
        
  • @Target:注解的作用目标       
    • @Target(ElementType.TYPE) //类、接口(包括注解类型) 或enum声明
    • @Target(ElementType.FIELD) //字段、枚举的常量
    • @Target(ElementType.METHOD) //方法
    • @Target(ElementType.PARAMETER) //方法参数
    • @Target(ElementType.CONSTRUCTOR) //构造函数
    • @Target(ElementType.LOCAL_VARIABLE)//局部变量
    • @Target(ElementType.ANNOTATION_TYPE)//注解
    • @Target(ElementType.PACKAGE) ///包
        
  • @Document:说明该注解将被包含在javadoc中,没有成员。

  • @Inherited:说明子类可以继承父类中的该注解

说明:

  1. Java内置了四种元注解。或许你要问了,这四种元注解又是哪里来的呢?我们来看看这三种元注解,得到的答案是每一种元注解又是建立在四个元注解的基础之上的。有点自己定义自己的意思。
  2. 什么时候使用这四个元注解?仅仅在你需要定义自己的注解类时。
  3. 什么时候使用自定义注解类或Java内置的几个标准注解类?当然是在普通Java类(指的是不是注解类的类如MetaAnnotation,有时候我也叫它被注解类)里使用。需要记住的是,普通Java类里并不能直接使用元注解,如果你在MetaAnnotation上面加上@Documented,肯定编译报错。
  4. @Target未指定任何参数的话,代表八种都包括。

MetaData

有一类事物,就可以定义一套元数据。
元数据(MetaData)相当于描述一类事物的属性列表,并且是标准的。
参考:
元数据(MetaData) - 阮一峰的网络日志

Inherited

Inherited作用是,使用此注解声明出来的自定义注解,在使用此自定义注解时,如果注解在类上面时,子类会自动继承此注解,否则的话,子类不会继承此注解。这里一定要记住,使用Inherited声明出来的注解,只有在类上使用时才会有效,对方法,属性等其他无效。

  • 1、Inherited是元注解,用来修饰自定义注解(比如CustonAnnotation)。
  • 2、类ParentClass在经CustonAnnotation修饰后,其子类ChildClass会自动继承CustonAnnotation。
  • 3、类ParentClass的属性和方法经CustonAnnotation修饰后,在ParentClass中有效,但其子类ChildClass如果覆盖父类的方法,那么子类的方法无法获取CustonAnnotation,属性一样的。

参考:
关于java 注解中元注解Inherited的使用详解 - 雪峰的专栏 - 博客频道 - CSDN.NET
Java注解学习四:@Inherited的使用 - zy19982004 - ITeye技术网站

Document

  • Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了@Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中.
  • javadoc中的@author、@version、@param、@return、@deprecated、@hide、@throws、@exception、@see是标记,并不是注解;

参考:
Java注解之Retention、Documented、Inherited介绍 - u013111003的博客 - 博客频道 - CSDN.NET
Android studio JavaDoc的使用

获取注解

常用方法一:isAnnotationPresent

isAnnotationPresent:检验是否存在该注解

isAnnotationPresent
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)

如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。

  • 参数:annotationClass - 对应于注释类型的 Class 对象
  • 返回:如果指定注释类型的注释存在于此对象上,则返回 true,否则返回 false
  • 抛出:NullPointerException - 如果给定的注释类为 null

常用方法二:getAnnotation

getAnnotation:获取注解

getAnnotation
<T extends Annotation> T getAnnotation(Class<T> annotationClass)

如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

  • 参数:annotationClass - 对应于注释类型的 Class 对象
  • 返回:如果该元素的指定注释类型的注释存在于此对象上,则返回这些注释,否则返回 null
  • 抛出:NullPointerException - 如果给定的注释类为 null

常用方法三:getAnnotations

getAnnotations:获取所有注解

getAnnotations
Annotation[] getAnnotations()

返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

  • 返回:此元素上存在的所有注释

常用方法四:getDeclaredAnnotations

getDeclaredAnnotations:获取除继承之外的所有注解,也就是直接存在于此元素上的所有注解。

getDeclaredAnnotations
Annotation[] getDeclaredAnnotations()

返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

  • 返回:直接存在于此元素上的所有注释

java注解 - YangYiBao - 博客园
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 | IT宅.com

关于@Target(ElementType.PACKAGE)

Java注解学习三:package-info.java的使用 - zy19982004 - ITeye技术网站
另类的package-info.java文件探讨 - - ITeye技术网站

在Android Studio中创建package-info.java:
The best workaround is to right click on the package, New, File, and create a file called package-info.java. Once it’s there the IDE will recognize it as a Java file and you’ll get the syntax highlighting and such.
How to create package-info.java in Android Studio - Stack Overflow

自定义注解

    使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
自定义注解格式:

    public @interface 注解名{注解体}
            1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
            2.String类型
            3.Class类型
            4.enum类型
            5.Annotation类型
            6.以上所有类型的数组

Annotation类型里面的参数该怎么设定:

  • 第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型; 
  • 第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;  
  • 第三,如果只有一个参数成员,最好把参数名称设为”value”,后加小括号.例:下面的例子FruitName注解就只有一个参数成员。
  • 第四,当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。

一小时搞明白自定义注解(Annotation) - 顾明伟 - 博客频道 - CSDN.NET
java自定义注解 - 永生 - ITeye技术网站
zy19982004的博客 - Java基础分类文章列表 - ITeye技术网站
深入理解Java:注解 - 牛奶、不加糖 - 博客园
这里写图片描述
Java中的注解是如何工作的? - ImportNew
http://www.importnew.com/10294.html

常见注解

API

Android开发过程中使用到的注解主要来自如下几个地方:

  • Android SDK:在包android.annotation下;

  • Android Annotation Support包:在包android.support.annotation下;

  • JDK:在包java.lang下;

  • 第三方框架中的自定义注解

最常见注解

@Override

属于标记注解,不需要设置属性值;只能添加在方法的前面,用于标记该方法是复写的父类中的某个方法,如果在父类没有的方法前面加上@Override注解,编译器会报错:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
    public @interface Override {
}

@Deprecated

&emsp;属于标记注解,不需要设置属性值;可以对构造方法、变量、方法、包、参数标记,告知用户和编译器被标记的内容已不建议被使用,如果被使用,编译器会报警告,但不会报错,程序也能正常运行:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER, ElementType.TYPE})
    public @interface Deprecated {
}

@SuppressWarnings

&emsp;可以对构造方法、变量、方法、包、参数标记,用于告知编译器忽略指定的警告,不用再编译完成后出现警告信息:

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

@TargetApi

可以对接口、方法、构造方法标记,如果在应用中指定minSdkVersion为8,但有地方需要使用API 11中的方法,为了避免编译器报错,在调用API11中方法的接口、方法或者构造方法前面加上@Target(11),这样该方法就可以使用<=11的API接口了。虽然这样能够避免编译器报错,但在运行时需要注意,不能在API低于11的设备中使用该方法,否则会crash(可以获取程序运行设备的API版本来判断是否调用该方法):

@Target({TYPE, METHOD, CONSTRUCTOR})
@Retention(RetentionPolicy.CLASS)
public @interface TargetApi {
    /**
     * This sets the target api level for the type..
     */
    int value();
}

@SuppressLint

和@Target的功能差不多,但使用范围更广,主要用于避免在lint检查时报错:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.CLASS)
public @interface SuppressLint {
    /**
     * The set of warnings (identified by the lint issue id) that should be
     * ignored by lint. It is not an error to specify an unrecognized name.
     */
    String[] value();
}

深入浅出Java注解 - 张明云的知识共享 - 知乎专栏

Android Annotation Support包中的注解

深入浅出Java注解 - 张明云的知识共享 - 知乎专栏

DEMO源码传送

相关文章:
APT技术 - qq_20198405的博客 - 博客频道 - CSDN.NET
ButterKnife - qq_20198405的博客 - 博客频道 - CSDN.NET
Dagger2 - qq_20198405的博客 - 博客频道 - CSDN.NET

注解

--
注解Annotation 示例、概念及作用、分类、自定义、解析,并对几个 Android 开源库 Annotation 原理进行简析
注解Android依赖注入:Dagger、RoboGuice和ButterKnife - 文章 - 伯乐在线
注解Dagger,ButterKnife,Roboguide,AndroidAnnotations框架的依赖注入浅析 - 爱悠闲,快乐工作,悠闲生活!

AndroidAnnotation

--
AndroidAnnotationAndroid注解AndroidAnnotation的使用及实现流程分析 - 简书
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值