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. cannot open clipboard 解决办法

    对于电脑本身或者一些应用程序操作的时候,会出现cannot open clipboard的问题,这是你系统没有剪切板程序 首先: 在开始->运行中输入clipbrd 回车, 如果系统弹出了剪切板 ...

  2. python 操作excel openpyxl

    1 安装 pip install openpyxl 如果装不上,请指定安装源来安装 pip install -i https://pypi.douban.com/simple openpyxl 如果e ...

  3. linux系统及命令学习

    1,基本概念 Shell(命令行):是一个程序,接受键盘输入的命令,并将命令传递给操作系统进行执行. Bash:Bourne Again Shell, 是大多数linux系统分之中所带的一种shell ...

  4. [go]gorhill/cronexpr用go实现crontab

    // crontab基础 // linux crontab // 秒粒度, 年配置(2018-2099) // 哪一分钟(0-59),哪小时(0-23),哪天(1-31),哪月(1-12),星期几(0 ...

  5. UI布局属性大全

    第一类:属性值为true或false android:layout_centerHrizontal 水平居中 android:layout_centerVertical 垂直居中 android:la ...

  6. Module ngx_http_rewrite_module

    http://nginx.org/en/docs/http/ngx_http_rewrite_module.html Directives     break     if     return    ...

  7. SDTP协议

    转载于 http://blog.csdn.net/fan_hai_ping/article/details/11797449 SDTP协议细则

  8. java.lang.reflect.Method.getAnnotation()方法示例【通过反射获取到方法对象再获取方法对象上的注解信息】

    转: java.lang.reflect.Method.getAnnotation()方法示例 java.lang.reflect.Method.getAnnotation(Class <T&g ...

  9. [spring]@Resource和@Autowired区别对比

    @Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包是javax.annotation.Resource,需要导入,但是Sprin ...

  10. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-2.微信扫一扫功能开发前期准备

    笔记 2.微信扫一扫功能开发前期准备         简介:讲解微信扫一扫功能相关开发流程和资料准备              1.微信开放平台介绍(申请里面的网站应用需要企业资料)          ...