Java反射(四)反射与注解
2021-02-19 18:20
标签:ima ati 连接 factor 运行 int voc 判断 生成 开发过程中使用注解将增加程序的灵活性和扩展性,注解可以修饰接口、类、方法、属性等。 能够通过反射获取类上的注解,主要依赖于核心类AccessibleObject(如下图,Java10的DOC),其实现了AnnotatedElement类。另外其子类包含Field、Executable(Method和Constructor)。 还可以通过该类可以设置属性的可见性,如getFields()获取所有属性,其中只包含父类的public属性,通过setAccessible(true),即可获取私有属性。 (1)获取注解主要方法: 获取所有注解(包含继承的):public Annotation[] getAnnotations() 获取指定注解(包含继承的):public 获取所有注解(不包含继承的):public Annotation[] getDeclaredAnnotations() 获取指定注解(不包含继承的):public (2)什么类型的注解可以通过反射获取到? ① 只有被Retention(RUNTIME)修饰的注解接口才可以通过反射在运行时获取,其中RUNTIME为 RetentionPolicy ② Retention注解标识对应注解维持到什么阶段,具体由RetentionPolicy决定 ③ 枚举类RetentionPolicy为注解维持策略,取值SOURCE(编译期)、CLASS(维持到class文件,默认值)、RUNTIME(维持到运行时) 如注解SuppressWarnings维持到SOURCE,无法通过反射获取到该注解 如功能接口注解FunctionalInterface,维持到RUNTIME,即可通过反射获取到该注解。 自定义注解:@interface. 下边是自定义注解,声明title,url(带默认值),seq(带默认值),并将注解修饰到方法上,如下: 测试:获取Method对象和对应的所有注解,并通过判断是否存在自定义的注解,进行调用对应方法,如下: 输出: 注解可以加强代码的复用,可以控制代码具体实现,下边举例综合工厂设计模式、代理和Annotation。 注解使用,通过该注解控制具体属性值,该例中设置clazz=MsgImpl.class,通过工厂生成代理后的对象,并赋给MsgService实例。 测试: 输出: 当把MsgService改为如下时,底层将执行NetMsgImpl对用的方法。 自定义注解可以控制代码具体实现,增加代码的复用。另外,将反射与注解结合,可以实现具备特定功能的框架,如Spring。 Java反射(四)反射与注解 标签:ima ati 连接 factor 运行 int voc 判断 生成 原文地址:https://www.cnblogs.com/shuimuzhushui/p/12676796.html1.反射获取注解
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,MODULE})
@Retention(SOURCE)
public @interface SuppressWarnings
@Documented
@Retention(RUNTIME)
@Target(TYPE)
public @interface FunctionalInterface
2.自定义注解
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
public String title();
public String url() default "www.baidu.com";
public int seq() default 0;
}
class Message{
@MyAnnotation(title = "message", seq = 1)
public void send(String msg, int seq){
System.out.println("消息发送:"+msg);
System.out.println("消息序号:"+seq);
}
}
public class AnnotationTest {
public static void main(String[] args) throws Exception{
Method method = Message.class.getDeclaredMethod("send", String.class, int.class);
Annotation[] anno = method.getDeclaredAnnotations();
for(Annotation an : anno){
if(an instanceof MyAnnotation){
MyAnnotation an1 = (MyAnnotation)an;
String msg =an1.title() + " " + an1.url();
method.invoke(Message.class.getDeclaredConstructor().newInstance(), msg, an1.seq());
}
}
}
}
消息发送:message www.baidu.com
消息序号:1
3.工厂设计模式与Annotation
/**
* 指定运行的注解类
*/
@Retention(RetentionPolicy.RUNTIME)
@interface ToClass{
public Class> clazz();
}
/**
* 工厂类
*/
class InstanceFactory{
private InstanceFactory(){}
public static
@ToClass(clazz = MsgImpl.class)
class MsgService{
private Msg msg;
public MsgService(){
ToClass clazzAnno = MsgService.class.getDeclaredAnnotation(ToClass.class);
msg = (Msg)InstanceFactory.getInstance(clazzAnno.clazz());
}
public void send(String text){
msg.send(text);
}
public String recv(String text){
return msg.recv(text);
}
}
interface Msg{
void send(String msg);
String recv(String msg);
}
class MsgImpl implements Msg{
public void send(String msg) {
System.out.println("消息发送:"+msg);
}
public String recv(String msg) {
System.out.println("消息接收:"+msg);
return msg;
}
}
public static void main(String[] args){
MsgService msgService = new MsgService();
msgService.send("hello");
msgService.recv("hello world");
}
创建连接
消息发送:hello
关闭连接
创建连接
消息接收:hello world
关闭连接
@ToClass(clazz = NetMsgImpl.class)
class MsgService{
.....
}
总结