进阶Java编程(13)反射与Annotation
1,反射取得Annotation信息
从JDK1.5之后Java提供了Annotation技术支持,这种技术为项目的编写带来了新的模型,而后经过了十年的发展,Annotation的技术得到了非常广泛的应用,并且已经在所有的项目开发之中都会存在。
获取Annotation信息
在进行类或方法定义的时候都可以使用一系列的Annotation进行声明,如果要想获取这些Annotation的信息,那么就可以直接通过反射来完成。在java.lang.reflect里面有一个AccessibleObject类,在本类中提供有获取Annotation类的方法:
①获取全部Annotation:public Annotation[] getAnnotations()
②获取指定Annotation:public <T extends Annotation> T getAnnotation(Class<T> annotationClass)

·范例:定义一个接口,并且在接口上使用Annotation
package com.mufasa.demo1; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; public class JavaAPIDemo {
public static void main(String[] args) throws NoSuchMethodException {
{//获取接口上的Annotation信息
Annotation[] annotations=IMessage.class.getAnnotations();
for(Annotation temp:annotations){
System.out.println(temp);
}
}
System.out.println("-------");
{//①获取MessageImpl子类上的Annotation,失败;②获取MessageImpl.toString方法
Method method=MessageImpl.class.getDeclaredMethod("send", String.class);
Annotation[] annotations=method.getAnnotations();
for(Annotation temp:annotations){
System.out.println(temp);
}
}
}
}
package com.mufasa.demo1;
/*
什么是函数式接口(Functional Interface)
其实之前在讲Lambda表达式的时候提到过,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。
这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。
函数式接口用途
它们主要用在Lambda表达式和方法引用(实际上也可认为是Lambda表达式)上。
*/
@FunctionalInterface
@Deprecated(since = "1.5")
interface IMessage {//现在这里有两个Annotation
public void send(String msg);
}
package com.mufasa.demo1;
import java.io.Serializable;
@SuppressWarnings("serial")//无法在程序执行的时候获取
public class MessageImpl implements IMessage, Serializable {
@Override
public void send(String msg) {
System.out.println("【消息发送】"+msg);
}
}
不同的Annotation有它存在的范围,下面对比两个Annotation:

现在发现【@FunctionalInterface】是在运行时生效的Annotation,所以当程序执行的时候可以获取此Annotation,而【@SuppressWarnings】是在源代码编写的时候有效。而在【RetentionPolicy】枚举类中还有一个class的定义,指的是类定义的时候生效。
2,自定义Annotation
现在已经清楚了Annotation的获取,以及Annotation的运行策略,但是最为关键性的一个因素是如何可以实现自定义的Annotation呢?为此在Java里面提供有新的语法,使用【@interface】来定义Annotation。
·范例:自定义Annotation
package com.mufasa.demo2; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME)//定义Annotation的运行策略
@interface DefaultAnnotation {//自定义Annotation
public String title();//获取数据
public String url() default "www.cnblogs.com";//获取数据,默认值
}
package com.mufasa.demo2; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class JavaAPIDemo {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Method method=Message.class.getMethod("send", String.class);//获取指定方法
DefaultAnnotation annotation=method.getAnnotation(DefaultAnnotation.class);//获取指定Annotation
// System.out.println(annotation.title());
// System.out.println(annotation.url());
String msg=annotation.title()+"("+annotation.url()+")";//消息内容
method.invoke(Message.class.getDeclaredConstructor().newInstance(),msg);
}
}
使用Annotation之后最大的特点就是可以结合反射机制实现程序的处理。
3,工厂设计模式与Annotation整合
现在已经清楚Annotation的整体作用,但是Annotation在开发之中能做哪些事情呢?为了帮助大家进一步理解Annotation的处理目的下面将结合工厂设计模式来应用Annotation操作。
package com.mufasa.demo3; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME)
public @interface UseMessage {
public Class<?> clazz();
}
package com.mufasa.demo3; @UseMessage(clazz = MessageImpl.class)//!!!通过注解来控制整个程序的完成!!!
public class MessageService {
private IMessage message;
public MessageService(){
UseMessage useMessage=MessageService.class.getAnnotation(UseMessage.class);
this.message=(IMessage) Factory.getInstance(useMessage.clazz());
}
public void send(String msg){
this.message.send(msg);
}
}
package com.mufasa.demo3;
public class JavaAPIDemo {
public static void main(String[] args){
//①普通
// IMessage msg=Factory.getInstance(MessageImpl.class);
// msg.send("www.cnblogs.com");
//②特殊
MessageService messageService=new MessageService();
messageService.send("www.cnblogs.com");
}
}
/*
【代理连接】进行消息发送通道的连接
【消息发送】www.cnblogs.com
【代理断开】关闭连接通道
*/
package com.mufasa.demo3;
import java.lang.reflect.InvocationTargetException;
class Factory {
private Factory(){}
public static <T> T getInstance(Class<T> clazz){//直接返回实例化操作对象
try{
return (T) new MessageProxy().bind(clazz.getDeclaredConstructor().newInstance());
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
由于Annotation的存在,所以对于面向接口的编程的配置处理将可以直接利用Annotation的属性完成控制,从而使得整体代码变得简洁。
进阶Java编程(13)反射与Annotation的更多相关文章
- 进阶Java编程(10)反射与简单Java类
1,传统属性自动赋值弊端 简单Java类主要由属性构成,并且提供有setter与getter类,同时简单Java类最大的特征就是通过对象保存相应的类属性的内容.但是如果使用传统的简单Java类开发,那 ...
- 进阶Java编程(9)反射与类操作
1,反射获取类结构信息 在反射机制的处理过程之中不仅仅只是一个实例化对象的处理操作,更多的情况下还有类的组成结构操作,任何一个类的基本组成结构:父类(父接口).包.属性.方法(构造方法与普通方法). ...
- 进阶Java编程(8)反射应用案例
1,反射实例化对象 经过一系列分析之后可以发现虽然获得了Class类的实例化对象但是依然觉得这个对象获取的意义不是很大,所以为了进一步的帮助大家理解反射的核心意义所在,下面将通过几个案例进行说明(都是 ...
- 进阶Java编程(7)反射机制
反射机制 1,反射机制简介 在Java语言里面之所以会有如此多的开源技术支撑,很大的一部分是来自于Java最大的特征[反射机制].如果你不能够使用反射机制去进行项目的开发与设计,那么可以说你并未接触到 ...
- Java编程之反射中的注解详解
"注解"这个词,可谓是在Java编程中出镜率比较高,而且也是一个老生常谈的话题.我们之前在聊Spring相关的东西时,注解是无处不在,之前我们简单的聊过一些"注解&quo ...
- 黑马程序员:Java编程_反射技术
=========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性 ...
- JAVA编程之——反射Reflect
说到反射,首先要说一下Java中的类和对象. 在Java中万事万物皆对象(有两个 例外,一个是普通数据类型,另一个是静态的东西,静态的东西不是对象的,是属于类的). 在Java中,类也是对象,类是ja ...
- Java编程基础-反射
一.java反射 1.反射:动态获取类的信息,以及动态调用对象的方法的功能.可以理解为动态看透类的能力. 2.主要功能:在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意 ...
- 进阶Java编程(11)ClassLoader类加载器【待完成】
1,ClassLoader类加载器简介 在Java里面提供一个系统的环境变量:ClassPath,这个属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指 ...
随机推荐
- yield and send的使用详细解释
https://blog.csdn.net/mieleizhi0522/article/details/82142856 虽然并不完全正确,但是能在使用中帮我们拨开迷雾 再结合另外一篇文章理解了htt ...
- LSTM参数和结构的本质理解——num_units参数/batch_size/cell计算
参考 ———— 图例讲解 https://blog.csdn.net/u014518506/article/details/80445283 理解:cell其实只有一个 : sequence leng ...
- k8s-helm02-----helm常用命令
查看在存储库中可用的所有 Helm charts helm search helm status 查询一个特定的 Release 的状态. helm status XXX
- python安装gmpy2模块时出现错误的解决
接下来表演的是安装Python模块gmpy2 此模块用来进行高精度计算的模块,个人根据需求常用来进行rsa加密算法的计算 作为一个资质浅淡的ubuntu玩家,这些知识当然是在网上搜索得到的,不过网上的 ...
- JVM学习笔记之认识JDK(一)
1. HotSpot VM: HotSpot VM是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机. 什么是HotSpot VM & 深入理解Java虚拟机 ...
- 003-tomcat配置文件-server、tomcat-users
1.server.xml讲解 位于conf下 <?xml version="1.0" encoding="UTF-8"?> <!-- Serv ...
- jdk1.8 HashMap源码分析(resize函数)
// 扩容兼初始化 final Node<K, V>[] resize() { Node<K, V>[] oldTab = table; int oldCap = (oldTa ...
- 数据中心网络架构的问题与演进 — 混合云与 VPC 专有网络
目录 文章目录 目录 前文列表 历史背景 混合云 Why hybrid cloud? 混合云市场 混合云的逻辑架构 混合云应用场景 灾难恢复 数据备份 负载扩容 应用部署 开发测试生产部署 混合云产品 ...
- [CDH] Acquire data: Flume and Kafka
Flume 基本概念 一.是什么 Ref: http://flume.apache.org/ 数据源获取:Flume.Google Refine.Needlebase.ScraperWiki.Bloo ...
- [ML] Machine Learning in the Common Infrastructure ecosystem
一.CogNet架构 下图,可见Kafka的作用. Partial code: Machine Learning in the Common Infrastructure ecosystem Rele ...