笔记目录
注解概述
注解是从Java的jdk5.0开始增加了对元数据(MetaData)的支持,就是Annotation(注解)属性。
Annotation属性其实就是代码中的特殊标记,通过这些一系列的标记可以在编译期、类加载时、运行时被读取,并执行对应的程序处理。通过Annotation属性程序员可以在不改变原有代码逻辑的情况下,在源文件中添加一些额外的属性功能。
Annotation可以像修饰符一样被调用,可用于修饰包、类、构造器、方法、成员变量、参数、局部变量的声明,这些信息被保存在Annotation的“name=value”对中,而在JavaSE中,注解使用的地方比较简单,例如标记过时的功能,忽略警告等。。注解在JavaEE方向占据了更重要的角色,例如用来配置应用程序的任何切面,替代JavaEE旧模式中所遗留的冗长的代码和xml配置。
常用注解
- 在使用Annotation属性时要在前面添加@符号,并把该属性当成一个修饰符来使用,用于修饰它要支持的程序代码。
生成文档相关的注解
- @author:表示开发该类模块的作者,如果有多个作者则用逗号分隔
- @version:表示该类模块的版本
- @see:该类的参考方向,和类功能相似的主题
- @since:从哪个版本开始增加的
- @param:对方法中参数的说明,没有参数就不能写
- @return:对方法返回值的说明,如果方法没有返回值则不能写
- @exception:对方法可能抛出异常进行说明,如果没有throw抛出的异常则不能声明
其中@param @return @exception这三个注解只能用作方法上面。
@param的格式要求:@param 形参名 形参类型 形参说明
@return的格式要求:@return 返回值类型 返回值说明
@exception的格式要求:@exception 异常类型 异常说明
@param和@exception可以并列多个
编译时注解(JDK内置的三个基本注解)
- @Override:表示重写父类的方法,该注解只能用于方法上面
- @Deprecated:用于表示修饰的元素(类,方法)已过时
- @SupperssWarnings:去除编译期警告
@Override注解用于修饰子类继承父类的方法或实现的方法。
例如
class Account {
public void login() {
System.out.println("账户登录");
}
}
//继承Account类
class User extends Account{
//加上了此注解之后如果修改子类方法名的话会报错,起到检查的作用。
@Override
public void login() {
System.out.println("用户登录");
}
}
@Deprecated注解是用于修饰某些类过时的方法,作为一种过时的提示来用。
//Date对象方法api很多都被标记了这个注解,例如调用下边的getYear()方法则会提示已过时,并在方法加上横线。
Date date = new Date();
date.getYear();
@SupperssWarnings是去除编译期的警告,例如变量和方法的未使用。
public class AnnotationDemo {
//忽略构造方法未使用的灰色警告
@SuppressWarnings("unused")
public AnnotationDemo() {}
//表示这个成员变量没有被使用,标注了此注解之后则灰色提示会消失
@SuppressWarnings(value = "unused")
int a = 20;
@SuppressWarnings("unused") //忽略方法的灰色提示警告
public void say() {}
public static void main(String[] args) {
//表示这个集合没有被使用,参数二表示泛型没有被指定,并忽略警告提示
@SuppressWarnings({"unused","rawtypes"})
ArrayList list = new ArrayList();
}
}
此外@SuppressWarnings({“unused”,“rawtypes”}) 忽略变量和泛型的设置可以定义在类上,则类中所有成员变量和方法都不会有灰色警告提示。
Java元注解
元注解是可以定义到注解上的注解,或者说元注解是一种基本注解,但是它能够应用到其它的注解上面。它的作用和目的就是给其他普通的注解进行增加功能并解释说明的。
元标签五个:@Retention、@Documented、@Target、@Inherited、@Repeatable
@Retention
@Retention只能用于修饰一个注解定义,用于指定其它注解的生命周期,@Retention包含一个RetentionPolicy枚举类型的成员变量,使用@Retention时必须为该value成员变量指定值。
RetentionPolicy枚举类有以下几个常量:
RetentionPolicy.SOURCE:注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
RetentionPolicy.CLASS:会被保留到class字节码文件中,不会被JVM读取。
RetentionPolicy.RUNTIME:会被保留到class字节码文件中,在运行时有效,会被JVM保留
@Target
@Target注解用于修饰Annotation定义,指定被修饰的注解能作用在哪些程序元素上,@Target也包含一个名为ElementType的成员变量。
ElementType常量:
-
TYPE: 只能作用于类,接口,枚举
-
METHOD:只能作用于方法上
-
FIELD:只能作用于成员变量上
-
PACKAGE 可以在包进行声明
-
ANNOTATION_TYPE 可以给一个注解进行注解
-
CONSTRUCTOR 可以给构造方法进行注解
-
LOCAL_VARIABLE 可以给局部变量进行注解
-
PARAMETER 可以给一个方法内的参数进行注解
-
TYPE_USE:可以作用于一个类中的任何语句中
-
TYPE_PARAMETER:表示该注解可以写在类型变量的语句中,例如声明在泛型前面
@Documented
@Documented注解用于指定被修饰的注解将被javadoc工具生成一个文档,默认javadoc不包括此注解。
定义@Documented的注解必须设置@Retention值为RUNTIME类型。
@Inherited
被这个注解修饰的自定义注解将具有继承的特性,如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解的功能。
例如:如果把标有@Inherited的注解的自定义注解标注在某一个类上,则继承这个类的子类也可以继承其注解的功能属性。
@Repeatable
@Repeatable注解表示可以重复使用同一个注解到一个类中
自定义注解
Java语言具有很强的可扩展性,由此也可以自定义新的Annotatio属性,需要使用@interface关键字。
自定义注解自动继承了 java.lang.annotation.Annotation 接口,Annotation 的成员变量在自定义注解中以无参数方法的形式来声明,其方法名和返回值定义了该成员的名字和类型,类型只能是八种基本数据类型、String、Class、enum、Annotation。
也可以在定义注解的成员变量时为其指定初始值,指定成员变量的初始值可用default关键字,如果只有一个参数则使用value,如果定义的注解含有配置参数,那么使用时必须指定参数值,除非有默认值,格式为:参数名 = 参数值,如果只有一个参数则可以忽略参数名称 。
示例:创建一个自定义注解指定默认值,并在自定义类上使用此注解,利用反射调用注解的值
自定义注解:
@Retention(value = RetentionPolicy.RUNTIME) //运行时加载到jvm中
@Target({ElementType.TYPE) //只能作用于类上面
public @interface MyAnnotation {
String str() default "Bear"; // 定义String属性
int age() default 0; //定义int属性
}
创建User类:
@Data //使用了Lombok依赖的注解,提供get&set方法
@MyAnnotation(str = "TED",age = 20) //指定注解属性的值
public class User {
}
这里通过反射类操作User对象并获取自定义注解中的值
public class AnnotationTest {
public static void main(String[] args) throws Exception {
Class<User> cl = User.class; //获取User的字节码对象
//调用getAnnotation方法并指定自定义注解的字节码对象
MyAnnotation annotation = cl.getAnnotation(MyAnnotation.class);
String str = annotation.str(); //调用定义的str属性
int age = annotation.age(); //调用定义的age属性
System.out.println(str); //打印变量
System.out.println(age);
}
}
打印结果为:TED,20