java基础解析系列(六)---注解原理及使用
java基础解析系列(六)---注解原理及使用
- java基础解析系列(一)---String、StringBuffer、StringBuilder
- java基础解析系列(二)---Integer缓存及装箱拆箱
- java基础解析系列(三)---HashMap原理
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
- java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别
- 这是我的博客目录,欢迎阅读
先来一个例子
class Father
{
public void f()
{}
}
public class Son extends Father{
@Override
public void f()
{}
}
- 当子类重写父类的方法的时候,上面会出现一个
@Override,这就是一个注解
@Controller
public class StudentController {
- 框架中的
@Controller也是一个注解
什么是注解
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
- 注解是一个接口
- 从某方面看,注解的作用就像修饰符(public,final,static)一样
- 程序可以通过反射来获取指定程序元素的Annotion,然后通过Annotion来获取注解里面的元数据。
注解的种类
- JDK内置系统注解
- 元注解,用于'修饰'注解
- 自定义注解
JDK内置系统注解
@Override
- 上面的例子已经展示,这个注解的作用是用于修饰覆盖了父类的方法
@Deprecated
- 这个注解是用来修饰已经过时的方法

- 可以看到当方法用@Deprecated修饰,然后使用这个方法的时候,编译器会提醒这个方法已经过时
@SuppressWarnnings
- 用于忽略编译器警告信息,告诉编译器停止对此方法的警告。
元注解
@Target
- 作用:被描述的注解可以用在什么地方
- 参数值
| ElementType | 含义 |
|---|---|
| ElementType | 含义 |
| ANNOTATION_TYPE | 注解类型声明 |
| CONSTRUCTOR | 构造方法声明 |
| FIELD | 字段声明(包括枚举常量) |
| LOCAL_VARIABLE | 局部变量声明 |
| METHOD | 方法声明 |
| PACKAGE | 包声明 |
| PARAMETER | 参数声明 |
| TYPE | 类、接口(包括注解类型)或枚举声明 |
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
@Target(ElementType.FIELD)
public @interface MyAnnotation {
}
- 上面是自定义的一个注解,用了一个@Target来修饰,表明这个自定义注解可以用来修饰域
@Retention
- 作用:指示注释类型的注释要保留多久
- 参数值
| RetentionPoicy | 意义 |
|---|---|
| SOURCE | 源文件中保留,比如@Override,用于与编译器交互 |
| CLASS | source,Class文件保留,用于编译时生成额外的文件 |
| RUNTIME | sorce,class文件,运行时保留 |
@Documented
- 作用:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化
- 被@Documented修饰的注解会生成到javadoc中
import java.lang.annotation.Documented;
@Documented
public @interface Demo
{
}
- 打开cmd,然后执行javadoc Demo.java,然后可以看到这个注解生成到了javadoc

@Inherited
- 作用:指示注释类型被自动继承。可以让子类对象使用getAnnotations()获取父类@Inherited修饰的注解。
@Inherited
@Retention( RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String msg() default "jiajun";
}
@MyAnnotation
class Father
{
}
class son extends Father{
}
public class Demo6
{
public static void main(String[] args) {
Father f=new son();
System.out.println(Arrays.toString(f.getClass().getAnnotations()));
}
}
//输出:[@MyAnnotation(msg=jiajun)]
自定义注解
格式
- public @interface 注解名 {定义体}
@Retention源码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
- 可以看到注解方法返回值是RetentionPolicy枚举类型
使用
- 用@interface(区别于interface)来声明一个注解
- 使用@interface定义注解的时候,自动继承了Annotation接口
- 用元注解修饰自定义注解
- 定义体里面可以定义一些参数成员,default设置默认参数值
- 使用注解的时候,传值方式(msg=""),当参数名是value的时候,可以直接用("666")的形式传值。
- 当没有传值的时候,
@MyAnnotation(),获取到的参数值是默认值
实验
@Retention( RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String msg() default "jiajun";
}
@MyAnnotation(msg="666")
class Test1
{}
public class Test2 {
public static void main(String[] args) {
Test1 t=new Test1();
Class c=t.getClass();
MyAnnotation ma = (MyAnnotation) c.getAnnotation(MyAnnotation.class);
System.out.println(ma.msg());
}
}
- 自定义了一个MyAnnotation注解,用Retention注解声明注解的生命周期,和Target修饰该注解的修饰范围
- Test1类用自定义的注解修饰,通过Class获取相关信息。当Rention修饰的不是RUNTIME的时候,不能获得相关信息
访问注解
访问类注解
@Retention( RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String name() default "jiajun";
}
@MyAnnotation(name="jiajun")
public class Test {
}
public static void main(String[] args) {
Class clazz = Test.class;
Annotation[] annotations = clazz.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
}
}
}
访问方法注解
@Retention( RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String name() default "jiajun";
}
public class Test {
@MyAnnotation(name="jiajun")
public void doSomething(){}
}
public class Demo {
public static void main(String[] args) {
Class clazz=Test.class;
Method[] methods=clazz.getMethods();
for(Method method :methods)
{
if(method.getName()=="doSomething")
{
Annotation annotation = method.getAnnotation(MyAnnotation.class);
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("name: " + myAnnotation.name());
}
}
}
}
}
访问参数注解
@Retention( RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface MyAnnotation {
String name() default "jiajun";
}
public class Test {
public static void doSomething(
@MyAnnotation(name="jiajun") String parameter){
}
}
public class Demo {
public static void main(String[] args) {
Class clazz=Test.class;
Method[] methods=clazz.getMethods();
for(Method method :methods)
{
if(method.getName()=="doSomething")
{
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();
int i=0;
for(Annotation[] annotations : parameterAnnotations){
Class parameterType = parameterTypes[i++];
for(Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("param: " + parameterType.getName());
System.out.println("name : " + myAnnotation.name());
}
}
}
}
}
}
}
- 每个方法有n个参数,每个参数包含一个注解数组,因此getParameterAnnotations()返回的是一个二维数组
我觉得分享是一种精神,分享是我的乐趣所在,不是说我觉得我讲得一定是对的,我讲得可能很多是不对的,但是我希望我讲的东西是我人生的体验和思考,是给很多人反思,也许给你一秒钟、半秒钟,哪怕说一句话有点道理,引发自己内心的感触,这就是我最大的价值。(这是我喜欢的一句话,也是我写博客的初衷)
作者:jiajun 出处: http://www.cnblogs.com/-new/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如果觉得还有帮助的话,可以点一下右下角的【推荐】,希望能够持续的为大家带来好的技术文章!想跟我一起进步么?那就【关注】我吧。
java基础解析系列(六)---注解原理及使用的更多相关文章
- java基础解析系列(六)---深入注解原理及使用
java基础解析系列(六)---注解原理及使用 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---Integer ja ...
- java基础解析系列(七)---ThreadLocal原理分析
java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...
- java基础解析系列(八)---fail-fast机制及CopyOnWriteArrayList的原理
fail-fast机制及CopyOnWriteArrayList的原理 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列( ...
- java基础解析系列(九)---String不可变性分析
java基础解析系列(九)---String不可变性分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---In ...
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...
- java基础解析系列(十一)---equals、==和hashcode方法
java基础解析系列(十一)---equals.==和hashcode方法 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系 ...
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...
- java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别
java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别 目录 java基础解析系列(一)---String.StringBuffer.St ...
- java基础解析系列(二)---Integer
java基础解析系列(二)---Integer 前言:本系列的主题是平时容易疏忽的知识点,只有基础扎实,在编码的时候才能更注重规范和性能,在出现bug的时候,才能处理更加从容. 目录 java基础解析 ...
随机推荐
- 【笔试面试】神马搜索C++程序猿电话面试
面试时间:2015.07.15 预约时间:2015.07.14.电话面试前一天,会电话咨询你方面电话面试的时间. 面试环节: 无自我介绍(这是我面试这么多家公司碰到的第一次),直接面试内容. 问题1: ...
- python与VScode
用VScode写python是非常方便的.vscode是一个功能非常强大的编辑器,下面介绍大致的使用方法: 下载安装python,配置环境变量. 下载安装VScode(vscode会自动连接pytho ...
- 【NodeJS】http-server.cmd
npm install http-server @echo off start cmd /k "D:\Program Files\nodejs\node_global\http-serve ...
- hbase shell 启动报错
启动hbase之后,发现hbase shell启动报错: version 2.0.0-alpha4, r5c4b985f89c99cc8b0f8515a4097c811a0848835, Tue Oc ...
- 执行RF设置顶层测试套件的描述说明
场景1:通过pybot命令更新套件层描述 命令:pybot -D 套件层描述 -D --doc documentation 设置顶层测试套件的描述说明.说明中下划线将转换为空格, 并且他可能包含简单的 ...
- java.lang.NumberFormatException: For input string: "${jdbc.maxActive}"
一.问题 使用SpringMVC和MyBatis整合,将jdbc配置隔离出来的时候出现下面的错误,百度了很久没有找到解决方法,回家谷歌下,就找到解决方法了,不得不说谷歌就是强大,不废话,下面是具体的错 ...
- ISD9160学习笔记04_ISD9160音频编码代码分析
前言 录音例程涉及了录音和播放两大块内容,上篇笔记说了播放,这篇就来说说录音这块,也就是音频编码这部分功能. 上篇笔记中的这段话太装逼了,我决定再复制下,嘿嘿. “我的锤子便签中有上个月记下的一句话, ...
- 剑指offer面试题7:用两个栈实现队列
题目1:用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 代码实现: public class Solution07 { Stack<Integer> ...
- JavaScript 简介--对javascript的初识,最基础的了解
一.javascript的介绍 JavaScript是网景(Netscape)公司开发的一种基于客户端浏览器.面向(基于)对象.事件驱动式的网页脚本语言.JavaScript语言的前身叫作Livesc ...
- DLL注入之Appinit_Dlls
AppInit_DLLs is a mechanism that allows an arbitrary list of DLLs to be loaded into each user mode p ...