Java Annotation详解(二): 反射和Annotation
前面一篇文《Java
Annotation详解(一): 理解和使用Annotation》中,我们或许会觉得,Annotation注释其实并没有多大的作用,除了几个内建的Annotation偶尔为了消除警告会使用下,自定义Annotation大家在实际的开发中应该都没有用过。其实呢,我在毕业后一年的工作里,也从未自定义使用过Annotation,只是在多处开发中使用过注释方便的内容,比如Servlet,Spring以及一些优秀的Android开源类库。 如果从简单的开发来讲,大家基本会使用一些开源的工具(只使用Annotation编写的)就好了,但是,如果大家能深入的了解Annotation,对大家学习这些开源框架将更有帮助。
Annotation何时才变得有意义呢? 如果结合反射,取得Annotation中设置的全部内容,Annotation的意义才会被最大化。
在以下的类中Class Constructor Field Method Package等类都实现了AnnotatedElement接口
在接口中有以下重要的方法:
· getAnnotations(Class annotationType)获取一个指定的annotation类型
· getAnnotations() 获取所有的Annotation
· getDeclaredAnnotations() 获取声明过的所有Annotation
· isAnnotationPresent(Class<? extends Annotation> annotationClass)这个annotation是否出现
通过这些方法,配合反射我们就可以在程序运行时拿到注解的内容了,例子如下:
首先定义一个普通的含有内建注释的类:
package com.test.reflectannotation ;
public class SimpleBeanOne{
@SuppressWarnings("unchecked")
@Deprecated
@Override
public String toString(){
return "Hello World!!!" ;
}
};
接下来,我们通过反射取出Annotation内容要注意,只有Deprecated的Annotation的定义范围是RUNTIME范围,所以此时通过反射的话,只能取得一个。
import java.lang.annotation.Annotation ;
import java.lang.reflect.Method ;
public class ReflectDemo01{
public static void main(String args[]) throws Exception{ // 所有异常抛出
Class <?> c = null ;
c = Class.forName("com.test.SimpleBeanOne") ;
Method toM = c.getMethod("toString") ; // 找到toString()方法
Annotation an[] = toM.getAnnotations() ; // 取得全部的Annotation
for(Annotation a:an){ // 使用 foreach输出
System.out.println(a) ;
}
}
};
输出:
@java.lang.Deprecated()
以上,我们取得的是内建的Annotation,接下来,我们自己定义一个Annotation:
package com.test.reflectannotation ;
import java.lang.annotation.Retention ;
import java.lang.annotation.RetentionPolicy ;
@Retention(value=RetentionPolicy.RUNTIME) // 此Annotation在类执行时依然有效
public @interface MyDefaultAnnotationReflect{
public String key() default "Linkage" ;
public String value() default "沉缘" ; }
我们通过RetentionPolicy指定了其值为RUNTIME,在运行时有效。
package com.test.reflectannotation ;
public class SimpleBeanTwo{
@SuppressWarnings("unchecked")
@Deprecated
@Override
@MyDefaultAnnotationReflect(key="Baidu",value="www.baidu.com")
public String toString(){
return "Hello World!!!" ;
}
};
通过反射取得指定的Annotation,因为现在唯一设置的内容就是MyDefaultAnnotationReflect。
import org.lxh.demo16.reflectannotation.MyDefaultAnnotationReflect ;
import java.lang.annotation.Annotation ;
import java.lang.reflect.Method ;
public class ReflectDemo{
public static void main(String args[]) throws Exception{ // 所有异常抛出
Class <?> c = null ;
c = Class.forName("com.test.reflectannotation.SimpleBeanTwo") ;
Method toM = c.getMethod("toString") ; // 找到toString()方法
if(toM.isAnnotationPresent(MyDefaultAnnotationReflect.class)){
// 判断是否是指定的Annotation
MyDefaultAnnotationReflect mda = null ;
mda = toM.getAnnotation(MyDefaultAnnotationReflect.class) ; // 得到指定的Annotation
String key = mda.key() ; // 取出设置的key
String value = mda.value() ; // 取出设置的value
System.out.println("key = " + key) ;
System.out.println("value = " + value) ;
}
}
};
输出:
key = Baidu
value = www.baidu.com
总结:
Annotation在实际的开发中,不管如何使用,其最终肯定结合反射机制,也就是说可以通过Annotation设置一些内容到方法上去,已完成特定的功能。
此外,发现有篇博客写的不错,是关于注解和反射的,可以参考:http://blog.csdn.net/a396901990/article/details/27961663
Java Annotation详解(二): 反射和Annotation的更多相关文章
- Java Annotation详解 理解和使用Annotation
系统中用到了java注解: 查了一下如何使用注解,到底注解是什么: (1)创建方法:MsgTrace Java Class==> 在Create New Class中: name:输入MsgTr ...
- Java多线程详解(二)
评论区留下邮箱可获得<Java多线程设计模式详解> 转载请指明来源 1)后台线程 后台线程是为其他线程服务的一种线程,像JVM的垃圾回收线程就是一种后台线程.后台线程总是等到非后台线程死亡 ...
- Java集合详解二
前一篇我们已经讲过了Collectin是存放单值的最大接口, 可以看到Map接口和其主要之类的关系图如下: 快速访问 HashMap HashTable TreeMap Map输出 那Map ...
- Java注解(Annotation)详解
转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...
- Java接口 详解(二)
上一篇Java接口 详解(一)讲到了接口的基本概念.接口的使用和接口的实际应用(标准定义).我们接着来讲. 一.接口的应用—工厂设计模式(Factory) 我们先看一个范例: package com. ...
- Shiro 安全框架详解二(概念+权限案例实现)
Shiro 安全框架详解二 总结内容 一.登录认证 二.Shiro 授权 1. 概念 2. 授权流程图 三.基于 ini 的授权认证案例实现 1. 实现原理图 2. 实现代码 2.1 添加 maven ...
- Java虚拟机详解----JVM常见问题总结
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- Java泛型详解(转)
文章转自 importNew:Java 泛型详解 引言 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用.本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理 ...
- Java Servlet详解(体系结构+注解配置+生命周期)
Java Servlet详解(注解配置+生命周期) 什么是Servlet : (Server applet)? 顾名思义:服务端的小程序 Servlet只是一个接口,定义了Java被浏览器访问到(To ...
随机推荐
- Linux下的MySQL主从同步
网上一些关于Linux下的MySQL主从同步教程非常之多,有些很简单的配置却弄的非常复杂,有些根本无法配通,下面是我通过简单的配置完成的主从同步过程,大家可以参考,此文章更适用于新手. 一.测试环境: ...
- Ubuntu下安装Mongo方法
场景:Ubuntu14下安装mongo,建议不要使用apt-get install 的命令安装,因为版本比较老 1.deb下载地址(可以自行选择OS,版本,server或tool或shell)http ...
- Codeforces Round #410 (Div. 2) A. Mike and palindrome【判断能否只修改一个字符使其变成回文串】
A. Mike and palindrome time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- 使用fast-json-stringify代替JSON.stringify
使用JSON.stringify的思考 使用过JSON对象的程序员最常做的一项工作便是,将JSON对象转化为字符串.该字符串的用途很多,例如可以使用在WEB的URL中,在多个页面间进行传递. cons ...
- Leetcode700.Search in a Binary Search Tree二叉搜索树中的搜索
给定二叉搜索树(BST)的根节点和一个值. 你需要在BST中找到节点值等于给定值的节点. 返回以该节点为根的子树. 如果节点不存在,则返回 NULL. class Solution { public: ...
- vue页面跳转传参
跳转页 this.$router.push({name:'路由命名',params:{参数名:参数值,参数名:参数值}}) 接收页 this.$route.params.参数名
- 时间模块(import time)
时间戳时间: float数据类型,给机器用的 print(time.time()) =>1533713657.5423343 结构化时间: 上下两种格式的中间状态 能够通过属性名来获取对象中的值 ...
- dialog的进度条
import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import and ...
- day13 memcache,redis上篇
memcache memcache简介 Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是以LiveJournal旗下Danga Interactive公司的B ...
- Linux进程管理(一、 基本概念和数据结构)
被问到两个问题, 后来想了下如果要讲明白还不太容易,需要对进程的概念,进程管理有清晰的认识: 1. 父进程打开了一个文件,然后通过fork创建一个子进程, 子进程是否共享父进程的文件描述符? 2. 在 ...