共计 3096 个字符,预计需要花费 8 分钟才能阅读完成。
1、注解概述
1.1、注解的定义
注解就是注释、解释的意思。只不过注解是一种更“官方”的解释性说明信息!
1.2、注解和注释的区别
注解的字面意思是注释、解释的意思,和 Java 中的注释一样,都有解释、说明的意思。
只不过,注释是程序猿自己写的,解释说明的对象是自己或者是其他程序猿 。而注解就不一样了, 注解 是一种很官方的解释,由 JDK 或者是咱们程序猿按照特定的格式定义,可以给咱们程序猿看,但更重要的是给 JVM 看,JVM 看了之后就会按照相应的注解信息去解释或执行被标注的程序。
比方:注释就是文言文上我们自己添加的对文言文的说明性信息;注解就是文言文下方官方添加的解释性信息。
总结:注释和注解都有解释说明的作用,只不过二者说明的对象的侧重点不同。注释是给人看的,而注解更多的是给 JVM 看!JVM 会根据注解信息执行响应的操作!
1.3、注解的历史
注解是 JDK1.5 之后才有的一门技术,本来 JDK 开发出注解这门技术的时候是想给自己用的,并没想到会给别人用,但是因为 java 是一门很开放的语言,或者说 sun 公司是一家很 open 的公司,所以就把实现注解的接口对外公开了。
很多公司发现有注解这门技术之后,发现很好用,于是就把他发扬光大了。
例如 Spring 公司、Hibernate、Struts2 等公司都支持注解开发!
1.4、注解的作用
-
直接作用:解释、说明
-
间接作用:替代配置文件(现在知道就行,中级的时候会讲)
1.5、注解的种类
- JDK 官方注解(原生注解)
- 自定义注解
- 元注解(元数据)
2、JDK 官方注解
@override: 检查子类是否是重写父类中的方法
@Deprecated:标记过时
@SuppressWarnings(“all”):压制错误警告
2.1、@override 代码演示
正确重写了父类方法
public class Person {public void eat(){System.out.println("人吃饭。。。");
}
}
public class Student extends Person {@Override
public void eat() {// 方法名正确,不会报错!
System.out.println("学生吃饭。。。");
}
}
错误重写了父类的方法
public class Person {public void eat(){System.out.println("人吃饭。。。");
}
}
public class Student extends Person {@Override
public void eot() {// 方法名写错了,编译器会报错!如果没有注解,则不会报错!
System.out.println("学生吃饭。。。");
}
}
错误信息
2.2、@Deprecated 代码演示
项目 1.0
public class DepDemo {public void methodA{// 这是项目 1.0 版本的时候的方法
}
}
项目 2.0
public class DepDemo {@Deprecated // 标记该方法为过时的方法
public void methodA(){// 该方法颜色会改变或有删除线
// 项目 2.0 版本的时候发现该方法不好!设计有问题,有缺陷!但不能删除或修改该方法!因为之前有人用,不希望以后的人再用他,所以把他标记为过时!
}
// 用 methodB 替代 methodA
public void methodB(){}}
添加 Deprecated 之后的效果图
2.3、@SuppressWarnings(“all”)
注解后面的()放的是注解的参数
压制错误警告!
@SuppressWarnings("all")
public class SupreWarDemo {public static void main(String[] args) {int i;
ArrayList list = new ArrayList<>();}
}
3、自定义注解
3.1、引入
定义类的关键字是 class
定义接口的关键字是 interface
定义枚举的关键字是 enum
那么定义注解的关键字是?@interface
大家现在可以把注解理解成一个 特殊的类,定义类的格式和定义注解的格式是一样的,只不过关键字换成注解的关键字而已。
3.2、格式
public @interface SelfDefAnno {
}
3.3、注解的成员有哪些?
类:成员变量、成员方法、构造方法
注解:成员变量(范围也有限定)
注解定义成员变量和类定义成员变量格式不一样
public @interface SelfDefAnno {String name();
int age() default 10;// 给默认值
// Date d(); 不可以 报错原因在下发
Class clazz();
Color c();// 枚举
int[] ages();
}
enum Color{RED,YELLOW;}
@interface SelfDefAnno2 {String name();
}
报错原因:only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof 只能是 8 种基本数据类型、Class 类型、注解类型,或者这些类型的一维数组
3.4、自定义注解的使用
类:对象 new 类型()
自定义注解:造对象 @==new
注解的参数就是注解定义时内部的成员变量
@SelfDefAnno(name="zs",age=18,clazz=int.class,c=Color.YELLOW,ages= {1,2,3},s=@SelfDefAnno2(name="zs"))
class A{ }
说明:注解前面说过其实就是一个特殊的类!这里的“@”符号其实就相当于是关键字“new”, 也就是说使用注解其实就是用注解这个“类”,创建一个对象!
注意:注解在使用的时候,其属性必须全部有值!要么定义的时候给默认值,要么使用的时候给指定值,二者必须出现其一!
注解:注解在使用时,里面的成员变量必须有值!如果不手动给值,他是不会有默认值!
3.5、default 关键字和 value 变量名
(1)default 关键字的使用 —–> 定义的时候给成员变量指定默认值
(2)value 变量名的特殊用法 —-> 给成员变量赋值时不用给变量名
4、元注解
4.1、概念解释
所谓元注解就是注解的注解,就是加在注解上的注解。
4.2、必须掌握的元注解
-
@Rentention:用于指定该 Annotation 可以保留的域
-
@Target:指定注解用于修饰类的哪个成员, 不指定,可以出现在任何位置
@Rentention
@Retention(RetentionPolicy.RUNTIME)//value=RetentionPolicy.RUNTIME
public @interface MetaAnno {
}
程序生命时机
@Retention 的参数有三个:
- RetentionPolicy.SOURCE:表示注解只在 源码 阶段有效!
- RetentionPolicy.CLASS:表示注解在 源码和编译 阶段有效!
- RetentionPolicy.RUNTIME:表示注解在 源码、编译和运行时 有效!
@Target
@Target(ElementType.FIELD)//value=ElementType.FIELD
public @interface MetaAnno {
}
@Target 注解中的参数至少有三个
- ElementType.FIELE : 表示能出现在 属性 上
- ElementType.METHOD:表示能出现在 方法 上
- ElementType.TYPE : 表示可以出现在 类上