JavaWeb学习-注解-3-反射注解
这篇来学习反射注解,前面我们知道如果需要使用反射,那么注解的保留策略一定要是RUNTIME类型。本篇来学习下如何通过反射获取作用在不同目标上的注解内容。
反射注解需要从作用目标上返回
- 类上的注解,需要从Class来获取
- 方法上的注解,需要从Method来获取
- 构造器上注解,需要从Construcation来获取
- 成员上注解,需要从Field上获取
根据前面学的,其实还有其他注解的作用目标,这里我们就看这四个来学习反射注解。上面四个类,Class类单独分一类,后面三个分一类。通过JDK查看后面三个类,都在reflect,反射包下,有一个共同父类AccessibleObject。
反射注解练习
这里来一个练习,先定义一个注解,然后看看反射注解。
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name();
int age();
String gender();
}
获取作用目标为类上注解信息
package annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
public class Demo1 {
}
@MyAnnotation(name="A类", age=18, gender="男")
class A{
@MyAnnotation(name="fun1方法", age=19, gender="女")
public void fun1() {
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name();
int age();
String gender();
}
先准备这段代码,我们在A类上和A类的方法中都使用了注解,那么如何获取A类上的注解信息,也就是如何通过代码拿到name="A类", age=18, gender="男" 这个信息。
package annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() {
// 1. 得到作用目标
Class<A> c = A.class;
// 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
MyAnnotation myAn = c.getAnnotation(MyAnnotation.class);
System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
}
}
@MyAnnotation(name="A类", age=18, gender="男")
class A{
@MyAnnotation(name="fun1方法", age=19, gender="女")
public void fun1() {
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name();
int age();
String gender();
}
运行输出结果是
A类, 18, 男
获取作用目标为方法上注解信息
下面代码来获取A类下的方法fun1()上的注解内容。
package annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() throws ReflectiveOperationException, SecurityException {
// 1. 得到作用目标, 这时候是方法
Class<A> c = A.class;
Method method = c.getMethod("fun1");
// 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
MyAnnotation myAn = method.getAnnotation(MyAnnotation.class);
System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
}
}
@MyAnnotation(name="A类", age=18, gender="男")
class A{
@MyAnnotation(name="fun1方法", age=19, gender="女")
public void fun1() {
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name();
int age();
String gender();
}
输出内容
fun1方法, 19, 女
获取构造器上注解信息
有了前面两个获取的基础,获取构造器就简单了,直接来看下面代码。
package annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() throws ReflectiveOperationException, SecurityException {
// 1. 得到作用目标,
Class<A> c = A.class;
Constructor constructor = c.getConstructor(); // 这种我们没写带参数的构造,参数为空
// 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
MyAnnotation myAn = (MyAnnotation) constructor.getAnnotation(MyAnnotation.class);
System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
}
}
@MyAnnotation(name="A类", age=18, gender="男")
class A{
// 构造器
@MyAnnotation(name="构造器", age=20, gender="不清楚")
public A() {
}
@MyAnnotation(name="fun1方法", age=19, gender="女")
public void fun1() {
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name();
int age();
String gender();
}
输出结果
构造器, 20, 不清楚
从输出结果来看,我们正确地得到了该作用目标的注解内容,下面来直接看字段注解如何获取。
package annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import org.junit.Test;
public class Demo1 {
@Test
public void fun1() throws ReflectiveOperationException, SecurityException {
// 1. 得到作用目标,
Class<A> c = A.class;
Field field = c.getField("userName");
// 2.获取指定类型的注解,当前我们这里类型就一个 MyAnnotation
MyAnnotation myAn = field.getAnnotation(MyAnnotation.class);
System.out.println(myAn.name() + ", " + myAn.age() + ", " + myAn.gender());
}
}
@MyAnnotation(name="A类", age=18, gender="男")
class A{
@MyAnnotation(name="成员变量", age=23, gender="男")
public String userName;
// 构造器
@MyAnnotation(name="构造器", age=20, gender="不清楚")
public A() {
}
@MyAnnotation(name="fun1方法", age=19, gender="女")
public void fun1() {
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name();
int age();
String gender();
}
输出结果
成员变量, 23, 男
这里提醒一下,为什么要在A类的成员变量写成public,如果你写成了private,那么就变成不可访问。打开Class的JDK文档,找到getField()方法,明确说了“返回一个 Field
对象,它反映此 Class
对象所表示的类或接口的指定公共成员字段”。
上一篇: 【.Net开发】之Entity Framework Core
下一篇: java反射