前言
月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂)
央是一片海洋,海乃百川,代表着一块海绵(吸纳万物)
泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出)
月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容
希望大家一起坚持这个过程,也同样希望大家最终都能从零到零,把知识从薄变厚,再由厚变薄!
一.注解是什么? 1.注解的定义
其实注解的定义,百度或者专业的人都解释的很清晰,这里小编为了防止刚学习的自己不够严谨直接摘抄了一个小编认为还很清晰的一个关于注解的定义:
Annontation是Java5开始引入的新特征,中文名称叫注解.他提供了一种安全的类似注释的机制,用来将任何信息或者元数据(metadata)与程序元素(类,方法,成员变量等)进行关联.为程序的元素(类,方法,成员变量) 加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用.Annontation像一种修饰符一样,应用于包,类型,构造方法,成员变量,参数及本地变量的生命语句中.
Java注解是附加在代码中的一些元信息,用于一些工具在编译,运行时进行解析和使用,起到说明,配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用
2.注解的原理注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类.而我们通过反射获取注解时,放回的是Java运行时生成的动态代理对象$Proxy1.通过代理对象调用自定义注解(接口)的方法,会最终调用AoontationInvocationHandler的invoke方法,该方法会从memberValues这个Map中索引出对应的值,而memberValues的来源是Java常量池.
3.注解的分类1.元注解:注解的注解,可以为注解添加信息描述,主要是用于自定义的注解,元注解在JDK中已被定义.
2.元注解包括@Target(注解的位置),@Retention(注解的作用范围),@documented(可以提取到javadoc,文档抽取),@Inherited(确认继承关系),@Native(确认某些内容可能来着本地代码中,比如C,或C++),@Repeatable(确认注解是否可重复.1.8时出),下面对以上元注解一一进行解释:
@Target
a.用法:用于设定注解的使用范围
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
b.Target通过ElementType来指定注解可使用的范围
public enum ElementType {
//标明该注解可以用于类,接口(包括注解类型)或enum声明
TYPE,
//标明该注解可以用于字段(域)声明,包括enum实例
FIELD,
//标明该注解可以用于方法声明
METHOD,
//标明该注解可以用于参数声明
PARAMETER,
//标明该注解可以用于构造函数声明
CONSTRUCTOR,
//标明注解可以用于局部变量声明
LOCAL_VARIABLE,
//标明注解可以用于注解声明(应用于另一个注解上)
ANNOTATION_TYPE,
//注明注解可以用于包声明
PACKAGE,
//标明注解可以用于类型参数声明
TYPE_PARAMETER,
//类型使用声明
TYPE_USE
特别注意:@Target缺省时,默认是支持全部的ElementType类型
其中,比较特别的两种,小编在这里单独提一下(其他的都是字面意思理解)
a).ElementType.PACKAGE.这个并不是简单的使用在一般类中,而是用在固定的文件package-info.java(而且命名一定是它)中
b).ElementType.TYPE_USE和Element.TYPE_PARAMETER两种java1.8新加入的两种,以前的注解是没有在方法类来进行的,现在加入了类型注解,让注解的应用更加广泛
@Retention
a.用法:作用于一个注解,标明当前注解能够保留到什么时候,表明一个注解的生命周期.缺省时默认为RetentionPolicy.CLASS
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
b.Retention的保留策略是由RetentionPolicy类中定义:
public enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME
}
@documented
a.用法:具有该类型的注解默认情况下会由javadoc和类似工具记录.如果类型声明使用documented进行注释,则其注释将成为注释元素的一部分API
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface documented {
}
@Inherited
a.使用该类型的注解后,只会影响类继承的接口继承,意思就是父类中使用了有该@Inherited元注解的自定义注解,那么子类也会继承下来,其他情况包括接口或者未使用时都不会继承(这一点在下面的源码中也解释的很清楚了)
package java.lang.annotation;
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
@Native和@Repeatable
前者我们基本上不会用到,被@Native注解修饰的成员变量,则表示这个变量可以被本地代码引用,常常被代码生成工具使用,我们基本不会使用,因此简单了解一下即可.
后者@Repeatable,是运行在相同的程序元素中重复注解,在需要对同一种注解多次使用时,往往需要借助@Repeatable注解
这两者网上资料也不多,小编自己也研究不深,在此不献丑了,等之后研究一番之后,在单独为其发一篇!
3.Java中内置的注解:
@Override
a). 相信大家对这个注解并不陌生,这个注解就是标注当前方法覆盖了当前父类或父接口的方法
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Deprecated
a).这个注解是标注当前对象即将被移除,已经有了更好的代替方案,建议大家不要在使用.
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
@FunctionalInterface
a).这个注解是1.8之后出来的函数式接口注释,标注当前接口是函数式接口,为了适用当前1.8中新特性,函数式编程,
b).特点:(直接看源码注释)
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}
@SafeVarargs
a). 使用场景,当出现一个编辑器觉得会出问题,但是你自己的代码里面不会涉及到的问题时,可以用这个来避免编辑器发出警告.具体来讲就是,可变长度的方法参数的实际值是通过数组来传递的,而数组中存储的是不可具象化的泛型类,自身存在类型安全问题,因此编译器会给出相应的警告消息
b).注意事项:该注解使用必须是可变参数方法和构造器;如果是可变参数的方法,那么必须用static和final来修饰才能使用
@documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}
@SuppressWarnings
a).此注解的作用是给编译器一条指令,告诉编译器对被批注的代码元素内部的某些警告保持静默.
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
| 关键字 | 用途 |
| all | 抑制所有警告 |
| boxing | 抑制与拆/装箱相关警告 |
| cast | 抑制与强制转换相关的警告 |
| dep-ann | 抑制与废弃注解相关的警告 |
| deprecation | 抑制与弃用相关的警告 |
| fallthrough | 抑制与switch语句中丢失的中断的相关的警告 |
| finally | 抑制finally块中不返回警告 |
| hiding | 抑制相对于隐藏变量的局部变量的警告 |
| incomlete-switch | 抑制相对于switch语句中丢失的条目相关的警告(枚举情况) |
| nls | 抑制与non-nls字符串相关的警告 |
| null | 抑制解析为空相关的警告 |
| rawtypes | 在类参数上使用泛型时,抑制与非特定类型相关的警告 |
| serial | 抑制与可序列化类缺少serialVersionUID字段相关的警告 |
| restriction | 抑制使用与禁止引用相关警告 |
| static-access | 抑制与不正确的静态访问相关的警告 |
| unchecked | 抑制与未检查操作相关的警告 |
| unqualified-field-access | 抑制与字段访问无关的警告 |
| unused | 抑制与未使用代码相关的jing |
二.Annotation
Annotation接口基本上就是所有的注解的Object了
public interface Annotation {
boolean equals(Object obj);
int hashCode();
//重写了Object的toString方法,
String toString();
//获取注解类型
//反射-->
Class extends Annotation> annotationType();
}
三.总结
总得来说,从最早接触Java语言,到真正去读源码去学习注解,才发现有很多地方是不太清晰的,但是现在依旧也很多地方很模糊,归根到底就是实际使用中,对这方面使用过少,导致很多地方含糊不清.说白了,小编还是太菜了,继续脱发,继续干吧!
月央泽,我怕变成越光泽...
以上内容,部分摘选自:
什么是注解? - 星朝 - 博客园
Java 注解(Annotation) | 菜鸟教程



