文章目录
一、定义
注解是JDK1.5之后的新特性,可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释,也叫元数据。
注解是说明程序的,给计算机看的标签
二、类型
1.JDK中预定义的注解
• @Override :检测被该注解标注的方法是否是继承自父类(接口)
• @Deprecated:该注解标注的内容,表示已过时
• @SuppressWarnings:压制警告,可以剔除编译时抛出的警告
一般传递参数all @SuppressWarnings(“all”)
2.自定义注解
自定义注解是用户自定义的注解,用于处理一些程序包含的注解无法处理的问题。
- 格式
元注解格式:
public @interface interface_name{
属性类型 属性名称1();
属性类型 属性名称2();
......
}
**元注解:用于描述注解的注解。**元注解也是一张标签,但是它是一张特殊的标签,它的作用和目的就是给其他普通的标签进行解释说明。
- 属性
自定义注解的属性定义类似于抽象方法,属性的返回值必须是:
- 基本数据类型
- String
- 枚举
- 注解
- 以上类型的数组
注意:
使用default关键字给属性默认初始化值,使用时,可以不用给属性赋值。
如果只有一个属性需要赋值,并且属性的名称是value,则使用时value可以省略,直接定义值即可。
数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略。
3.元注解
@Target(ElementType.${param})
作用:描述注解能够作用的位置。
参数${param}取值:
- TYPE:作用于类;
- METHOD:作用于方法;
- FIELD:作用于成员变量
@Retention(RetentionPolicy.${param})
作用:注解的生命周期,描述注解被保留的阶段。
参数${param}取值:
- SOURCE:只保留到源码阶段;
- CLASS:保留到CLASS对象阶段;
- RUNTIME:保留到运行期阶段。
一般自定义注解都定义到保留阶段。
@Document
作用:被其标注的注解将会生成在文档中。
@Inherited
作用:将父类的注解继承给子类。
此注解只对子类生效,对子类的方法、属性无效,即子类的方法和属性不会继承父类的注解。
三、注解与反射
1.获取类上的注解
A a = (A) Class.getAnnotation(A.class)//A为类上的注解
2.获取方法上的注解
B b = method.getAnnotation(B.class)//B为方法上的注解
3.判断判断方法对象是否有该注解,如果有则获取注解对象
method.isAnnotationPresent(B.class)
四、注解与反射结合(实战)
需求:
实现功能,通过获取自定义注解中配置的用户名、密码,判断输入的用户名和密码是否匹配。
需求分析:
- 自定义注解,属性为用户名和密码,类型为String。
- 定义login方法,配置用户名,密码的初始值。
- 通过反射获取login方法的注解。
- 接收输入用户名、密码,并和注解中的配置进行匹配验证,一致输出匹配,否则输出用户名、密码错误
代码如下。
1.自定义注解Verify
package annotation.user_matching;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Verify {
//用户只有一个,所以我直接配置在了注解里
String userName() default "Iron";
String passWord() default "loveyou3000";
}
2.登录类Login
package annotation.user_matching;
public class Login {
@Verify()//定义在方法上的注解
public void login() throws InterruptedException {
//定义login方法,验证成功后执行
System.out.println("\n\n身份验证通过!\n醒醒贾维斯,游戏时间到了。");
}
}
3.测试类Test
package annotation.user_matching;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLOutput;
import java.util.Scanner;
public class Test {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, InterruptedException {
//获取class对象
Class clazz = Class.forName("annotation.user_matching.Login");
Login login = (Login) clazz.newInstance();
//获取方法对象
Method method = clazz.getMethod("login");
//判断方法对象是否有该注解,如果有则获取注解对象
if(method.isAnnotationPresent(Verify.class)){
Verify verify = method.getAnnotation(Verify.class);
//获取用户数据
String name = verify.userName();
String psd = verify.passWord();
//获取输入数据
Scanner scanner = new Scanner(System.in);
System.out.println("用户名?");
String userName = scanner.nextLine();
//校验用户名
if (userName.equals(name)) {
System.out.println("用户名核验成功!");
}else {
System.out.println("参数错误。\n来源: 用户名 核验失败");
return;
}
System.out.println("密码?");
String passWord = scanner.nextLine();
//核验密码
if (passWord.equals(psd)) {
System.out.println("密码核验成功!");
}else {
System.out.println("参数错误。\n来源: 密码 核验失败");
return;
}
//校验通过
method.invoke(login);
}
}
}