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的更多相关文章

  1. 进阶Java编程(10)反射与简单Java类

    1,传统属性自动赋值弊端 简单Java类主要由属性构成,并且提供有setter与getter类,同时简单Java类最大的特征就是通过对象保存相应的类属性的内容.但是如果使用传统的简单Java类开发,那 ...

  2. 进阶Java编程(9)反射与类操作

    1,反射获取类结构信息 在反射机制的处理过程之中不仅仅只是一个实例化对象的处理操作,更多的情况下还有类的组成结构操作,任何一个类的基本组成结构:父类(父接口).包.属性.方法(构造方法与普通方法). ...

  3. 进阶Java编程(8)反射应用案例

    1,反射实例化对象 经过一系列分析之后可以发现虽然获得了Class类的实例化对象但是依然觉得这个对象获取的意义不是很大,所以为了进一步的帮助大家理解反射的核心意义所在,下面将通过几个案例进行说明(都是 ...

  4. 进阶Java编程(7)反射机制

    反射机制 1,反射机制简介 在Java语言里面之所以会有如此多的开源技术支撑,很大的一部分是来自于Java最大的特征[反射机制].如果你不能够使用反射机制去进行项目的开发与设计,那么可以说你并未接触到 ...

  5. Java编程之反射中的注解详解

    "注解"这个词,可谓是在Java编程中出镜率比较高,而且也是一个老生常谈的话题.我们之前在聊Spring相关的东西时,注解是无处不在,之前我们简单的聊过一些"注解&quo ...

  6. 黑马程序员:Java编程_反射技术

    =========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性 ...

  7. JAVA编程之——反射Reflect

    说到反射,首先要说一下Java中的类和对象. 在Java中万事万物皆对象(有两个 例外,一个是普通数据类型,另一个是静态的东西,静态的东西不是对象的,是属于类的). 在Java中,类也是对象,类是ja ...

  8. Java编程基础-反射

    一.java反射 1.反射:动态获取类的信息,以及动态调用对象的方法的功能.可以理解为动态看透类的能力. 2.主要功能:在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意 ...

  9. 进阶Java编程(11)ClassLoader类加载器【待完成】

    1,ClassLoader类加载器简介 在Java里面提供一个系统的环境变量:ClassPath,这个属性的作用主要是在JVM进程启动的时候进行类加载路径的定义,在JVM里面可以根据类加载器而后进行指 ...

随机推荐

  1. gradle添加阿里云maven库

    用gradle构建spring项目,才发现gradle要添加阿里云maven库和maven不太一样 链接:https://www.cnblogs.com/SiriYang/p/10638365.htm ...

  2. ECharts3D地图(详细示例——附有具体注释)

    3D地图图表效果如下: 具体代码如下: <!DOCTYPE html><html><head> <meta charset="UTF-8" ...

  3. Java-NIO 之 Buffer 与 Channel

    NIO:一种同步非阻塞的 I/O 模型,也是 I/O 多路复用的基础. 同步与异步 同步:发起一个调用后,被调用者未处理完请求之前,调用不返回. 异步:发起一个调用后,立刻得到被调用者的回应表示已接收 ...

  4. SpringCloud(三)之Feign实现负载均衡的使用

    一 点睛 Feign是Netflix开发的声明式.模板化的HTTP客户端, Feign可以帮助我们更快捷.优雅地调用HTTP API. 在Spring Cloud中,使用Feign非常简单——创建一个 ...

  5. 2.使用kubeadm快速搭建k8s集群

    准备工作: 时间同步 systemctl stop iptables.servicesystemctl stop firewalld.service 安装docker wget https://mir ...

  6. Hive的内部表和外部表

  7. Python中第三方库Requests库的高级用法详解

    Python中第三方库Requests库的高级用法详解 虽然Python的标准库中urllib2模块已经包含了平常我们使用的大多数功能,但是它的API使用起来让人实在感觉不好.它已经不适合现在的时代, ...

  8. python解析模块(ConfigParser)使用方法

    python解析模块(ConfigParser)使用方法 很多软件都有配置文件,今天介绍一下python ConfigParser模块解析配置文件的使用方法 测试配置文件test.conf内容如下: ...

  9. delphi数据集查找不定位

    procedure TForm1.Button2Click(Sender: TObject); var R: Variant; begin R := MemTableEh1.Lookup('Name' ...

  10. Mac运行React Native安卓项目报错解决

    传送门参考: 下面的这个链接很详细了,一步一步就好.... https://github.com/NARUTOyuyang/React-Native 然而在运行react-native run-and ...