注解
1. 简介
- 注释:用于解释说明代码 主要用于提供给程序查看
- 注解:用于对代码进行解释说明 主要提供给jvm来进行查看
- 定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,
用来对这些元素进行说明,注释
A.在jdk1.5之后引用的新的特性 B.用于对元素进行说明 注释 C.注解又称 元数据 - 作用分类:
A.编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
B.代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
C.编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
2.jdk提供注解
-
@Override 用于检查是否是重写的方法
-
@Deprecated 用于来标注是过时的方法 但是这个方法还是可以使用 stop()
-
SuppressWarnings 压制黄色的警告线
SuppressWarnings(“all”) 压制所有的黄色的警告线 可以定义在类上 也可以定义方法上 还可以定义在属性上
3. 自定义注解
1.定义:
A.元注解
B.public @interface SuppressWarnings {}
2.本质: 本质就是一个接口
public interface My extends java.lang.annotation.Annotation {}
3.接口的成员: 静态的常量(不要关注) 抽象方法(关注) 注解中的成员称为是属性
4.注解中属性的返回值类型
A.基本数据类型 四类八种
B.String类型
C.枚举类型
D.注解类型
E.以上类型的数组类型
5.注意点
A.使用注解的时候 必须给其所有的属性(抽象方法)来进行赋值
B.使用的注解的时候 如果没有属性赋值 那么属性必须设置默认值
C.使用注解的时候 给属性是数组进行赋值 设置多个值使用大括号 如果只设置一个值 可以省略大括号
D.如果注解只有一个属性 这个属性名是value 使用注解的时候 可以省略属性名 直接进行赋值
4. 元注解
- @Target 主要用于来表示注解作用的位置
- TYPE 表示在类上面可以使用
- FIELD 表示在属性上可以使用
- METHOD 表示在方法上可以使用
- @Retention 主要用于注解是否可以被识别
- RUNTIME 表示项目在运行的时候 jvm可以识别这个注解
- @Inherited 用于表示注解是否继续被子类继承的使用
- @Documented 用于标注是否在api文档上显示这个注解
5 .案例-使用注解动态调用一个类的方法
分析:
A.定义注解类
属性: 设置类的完整包名+类名
属性: 设置的方法的名称
使用元注解: @Target @Retention
B.定义测试类给属性进行赋值
step03 -定义类
public class Student {
public void showInfo(){
System.out.println("66666666666666666");
}
}
step04 定义一个注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
String classname();
String methodname();
}
step05 测试类
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@MyAnno(classname = "com.ahao.Student",methodname = "showInfo")
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取Class对象
Class cla = Test01.class;
//获取注解对象
MyAnno myAnno = (MyAnno) cla.getAnnotation(MyAnno.class);
//获取属性值
String classname = myAnno.classname();
String methodname = myAnno.methodname();
Class cla1 =Class.forName(classname);
//获取构造方法
Constructor con = cla1.getConstructor();
//实例化对象
Object o = con.newInstance();
//获取方法对象
Method method = cla1.getMethod(methodname);
//调用方法
method.invoke(o);
}
}
6. 案例-注解和反射给属性赋值
使用注解给学生的属性name 与age进行赋值并且获取
代码-注解类:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String classname();
String name();
int age();
}
代码-学生类:
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
代码-测试类:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@MyAnnotation(classname = "com.ahao.homework.demo01.Student",name="阿豪",age = 18)
public class Test {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException, InvocationTargetException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
//获取Class对象
Class<Test> cla = Test.class;
//获取注解对象
MyAnnotation myAnnotation = cla.getAnnotation(MyAnnotation.class);
//获取属性值
String classname = myAnnotation.classname();
String name = myAnnotation.name();
int age = myAnnotation.age();
//获取学生类反射对象
Class<?> cla1 = Class.forName(classname);
//获取构造方法
Constructor<?> con = cla1.getConstructor();
//创建对象
Object o = con.newInstance();
//调用方法给属性赋值
Field field1 = cla1.getDeclaredField("name");
Field field2 = cla1.getDeclaredField("age");
field1.setAccessible(true);
field2.setAccessible(true);
field1.set(o,"法外狂徒");
field2.set(o,18);
//获取
Field[] fields = cla1.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
System.out.println(field.get(o));
}
}
}