java注解

慕课网

前言

  • 注解就是代码中出现的@
  • 学习注解能够看懂别人写的代码,特别是框架相关的代码
  • 让编程更简单,代码更加清晰
  • 能让别人高看一眼,会使用自定义注解

注解是Java提供了一种源程序中的元素关联任何信息和任何元数据的途径和方法

jdk中的注解

1
2
3
@Override //重写覆盖的注释
@Deprecated //过时注释,用在已经过时的方法上,此时调用该方法会中间有一个横线并且有警告
@SuppressWarnings("deprecation")//压缩警告,如果实在要调用上面的方法但是不想要警告,在调用上面方法的方法前加上这个注释,就不会有警告

注解分类

  • 按照运行机制分:1.源码注解、2.编译时注解、3.运行时注解
  1. 源码注解:只在源代码中存在,编译成class后就不存在了
  2. 编译时注解:注解在源码和class中都存在,告诉编译时候的注解,比如@Override
  3. 运行时注解,在运行阶段还会起作用,甚至会影响运行逻辑
  • 按照来源分类:1.来自jdk的注解、2.来自第三方的注解、3.自定义注解

元注解:注解的注解

自定义注解

一个小栗子

1
2
3
4
5
6
7
8
9
10
11
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyDescription {
String desc();

String author();

int age() default 18;
}
  • 用@interface修饰注解
  • 成员以没有参数没有异常的方式来声明
  • 成员可以指定一个default值
  • 成员类型是受限的,合法的类型有基本类型(int,double…)和String,Class,Annotation,Enumeration
  • 如果注解只有一个成员,则成员名只能是value(),在使用的时候可以忽略成员名和赋值(=)
  • 注解类可以没有成员,没有成员的注解成为标识注解

元注解

1
2
3
4
5
6
7
8
9
10
@Target({ElementType.METHOD, ElementType.TYPE})
/*Target是注解的作用域
CONSTRUCTOR:构造方法声明
FIELD:字段声明
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口
*/
1
2
3
4
5
6
@Retention(RetentionPolicy.RUNTIME)
/*生命周期注解,即上面按照运行时分类
SOURCE:只在源码显示,编译时会丢失
CLASS:编译时会记录到class中,运行时忽略
RUNTIME:运行时存在,可以通过反射读取
*/
1
2
@Inherited
/*表示允许子类继承*/
1
2
@Documented
/*生成javaDoc的时候会包含注解的信息*/

自定义注解的使用

使用注解的语法
@<注解名>(<成员名>=<成员值>,<成员名2>=<成员值2>)
放在相应的类或方法上

1
2
3
4
5
6
7
@MyDescription(desc = "hello class", author = "world class",age = 19)
public class Father {
@MyDescription(desc = "hello method", author = "world method",age = 19)
public void hh(){

}
}

解析自定义注解

概念:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public static void main(String[] args) {
try {
//通过反射获取类
Class c = Class.forName("cn.xwmdream.main.Father");

//获得类上的注解
if (c.isAnnotationPresent(MyDescription.class)) {
MyDescription m = (MyDescription) c.getAnnotation(MyDescription.class);
System.out.println(m.author());
}

//获得方法上的注解
Method[] methods = c.getMethods();
for (Method m : methods) {
if(m.isAnnotationPresent(MyDescription.class)){
MyDescription d = (MyDescription)m.getAnnotation(MyDescription.class);
System.out.println(d.age());
}
}
//另一种解析方式
for (Method m:methods){
Annotation[] annotations = m.getAnnotations();
for (Annotation a : annotations){
if(a instanceof MyDescription){
MyDescription d = (MyDescription)a;
System.out.println(d.desc());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

注解的继承

  • 注解的继承不能继承接口的注解,只能继承父类的注解
  • 注解的继承只能继承类的注解,不能继承方法的注解