我们都知道从JDK1.5开始,注解开始被支持使用,当我们在使用注解的时候感觉比配置文件用起来更加简便和清爽。配置文件是通过解析配置文件的内容获取到数据,那么为什么仅仅在类、方法或者属性上添加注解被注解对象就内部就能获取到注解内部的数据了呢?

一、给类添加单个注解

1、自定义一个注解:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
String methodName();
}

2、定义一个类用于测试类通过反射创建对象调用其内部方法

/**
* @Classname User
* @Description TODO
* @Date 2020/9/16 17:28
* @Created by Administrator
*/
public class User {
public void eat(){
System.out.println("吃饭...");
} public void drink(){
System.out.println("喝水...");
}
}

3、定义一个测试类用于测试注解内数据是如何被获取到的

import java.lang.reflect.Method;

/**
* @Classname AnnotationClassTest
* @Description TODO
* @Date 2020/9/16 17:29
* @Created by Administrator
*/
@Pro(className = "User",methodName = "eat")
public class AnnotationClassTest {
public static void main(String[] args) throws Exception {
// 1 获取被注解位置的字节码对象
Class<AnnotationClassTest> testClass = AnnotationClassTest.class;
// 2 根据注解的字节码对象创建注解对象
Pro annotation = testClass.getAnnotation(Pro.class);
// 3 根据注解对象获取注解内部数据
String className = annotation.className();
String methodName = annotation.methodName();
// 3.1打印获取到的注解数据
System.out.println(className);
System.out.println(methodName);
// 4 通过反射通过获取到的className获取该类字节码对象
Class aClass = Class.forName(className);
// 5 通过该字节码对象根据获取到的methodName获取方法对象
Method method = aClass.getMethod(methodName);
// 6 通过类字节码对象生成该类对象
User user= (User) aClass.newInstance();
// 7 方法执行
method.invoke(user);
}
}

二、给方法添加单个注解

1、自定义一个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro2 {
String className();
String methodName();
}

2、定义一个类用于测试类通过反射创建对象调用其内部方法

/**
* @Classname User
* @Description TODO
* @Date 2020/9/16 17:28
* @Created by Administrator
*/
public class User {
public void eat(){
System.out.println("吃饭...");
} public void drink(){
System.out.println("喝水...");
}
}

3、定义一个测试类用于测试注解内数据是如何被获取到的

import java.lang.annotation.Annotation;
import java.lang.reflect.Method; /**
* @Classname AnnotationClassTest
* @Description TODO
* @Date 2020/9/16 17:29
* @Created by Administrator
*/ public class AnnotationMethodTest {
@Pro2(className = "User",methodName = "eat")
public static void main(String[] args) throws Exception {
// 1 获取被注解位置的字节码对象
Class<AnnotationMethodTest> testClass = AnnotationMethodTest.class;
// 2 根据注解的字节码对象创建注解对象
Pro2 annotation = testClass.getMethod("main", String[].class).getAnnotation(Pro2.class);
// 3 根据注解对象获取注解内部数据
String className = annotation.className();
String methodName = annotation.methodName();
// 4 通过反射通过获取到的className获取该类字节码对象
Class aClass = Class.forName(className);
// 5 通过该字节码对象根据获取到的methodName获取方法对象
Method method = aClass.getMethod(methodName);
// 6 通过类字节码对象生成该类对象
User user= (User) aClass.newInstance();
// 7 方法执行
method.invoke(user);
}
}

三、给类添加多个注解

1、自定义两个注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {
String className();
String methodName();
}

自定义注解1

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* @Classname Pro
* @Description TODO
* @Date 2020/9/16 17:27
* @Created by Administrator
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro3 {
String className();
String methodName();
String age();
}

自定义注解2

2、定义一个类用于测试类通过反射创建对象调用其内部方法

/**
* @Classname User
* @Description TODO
* @Date 2020/9/16 17:28
* @Created by Administrator
*/
public class User {
public void eat(){
System.out.println("吃饭...");
} public void drink(){
System.out.println("喝水...");
}
}

3、定义一个测试类用于测试注解内数据是如何被获取到的

import java.lang.reflect.Method;

/**
* @Classname AnnotationClassTest
* @Description TODO
* @Date 2020/9/16 17:29
* @Created by Administrator
*/
@Pro(className = "User",methodName = "eat")
@Pro3(className = "User",methodName = "drink",age = "23")
public class AnnotationClassTest2 {
public static void main(String[] args) throws Exception {
// 1 获取被注解位置的字节码对象
Class<AnnotationClassTest2> testClass = AnnotationClassTest2.class;
Pro annotation = testClass.getAnnotation(Pro.class);
String className = annotation.className();
String methodName = annotation.methodName();
Class aClass = Class.forName(className);
Method method = aClass.getMethod(methodName);
User user= (User) aClass.newInstance();
method.invoke(user); Pro3 annotation2 = testClass.getAnnotation(Pro3.class);
String className2 = annotation2.className();
String methodName2 = annotation2.methodName();
Class aClass2 = Class.forName(className2);
Method method2 = aClass2.getMethod(methodName2);
User user2= (User) aClass2.newInstance();
method2.invoke(user2);
}
}

总结

之所以被注解内部能够获取注解内部数据根本原因就在于通过被注解对象字节码文件能够获取到该对象字节码文件中是否含有注解,并能够通过该字节码文件获取注解内部数据,因此更简便的实现了配置文件相同的功能。

Java注解之获取注解内部数据的原因分析的更多相关文章

  1. 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)

    目录 自定义注解 定义切面 获取上下文信息JoinPoint ProceedingJoinPoint 定义测试方法 测试结果 小结 AOP可以用于日志的设计,这样话就少不了要获取上下文的信息,博主在设 ...

  2. 使用C#利用cmd来调用java jar包获取其中的数据

    其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...

  3. spring + mybatis 注解式事务不回滚的原因分析 @Transactional

    在一个项目中发现spring的事务无法回滚. DEBUG: org.mybatis.spring.SqlSessionUtils - SqlSession [org.apache.ibatis.ses ...

  4. C++ Win 32 使用原始套接字获取所有ip数据包并分析(包括ping包)

    /*页面编码:GBK 开发环境 VS2019 */ #define _WINSOCK_DEPRECATED_NO_WARNINGS#include <iostream>#include&l ...

  5. 关于在Java中链接SQLServer数据库中失败的原因分析

    首先声明:笔者是Java的初学者,并且一值是走在自学的道路上,长久以来只有“度娘”相伴.(加入了各种Java学习群,基本没有热心帮人解决问题的.可以理解-_-!!!)大神级的人物就不必看拙文了,没有什 ...

  6. java内存泄露/溢出等常见问题模拟及原因分析

    Java 8:从持久代到metaspace 系统稳定性--OutOfMemoryError 常见原因及解决方法 java各种异常问题示例(附pdf下载): java.lang.OutOfMemoryE ...

  7. Jsoup获取全国地区数据(省市县镇村)

    最近手头在做一些东西,需要一个全国各地的地域数据,从省市区到县镇乡街道的.各种度娘,各种谷歌,都没找到一个完整的数据.最后功夫不负有心人,总算找到一份相对来说比较完整的数据,但是这里的数据也只是精确到 ...

  8. SpringMVC_01 SpringMVC五大组件、SpringMVC编程步骤(不使用注解进行配置)、SpringMVC编程步骤(利用注解进行配置)、参数获取、响应数据

    1 什么是SpringMVC 是一个mvc框架,用来简化基于mvc架构的web应用程序的 开发. 2 SpringMVC五大组件 DispatcherServlet (前端控制器) HanlderMa ...

  9. java反射获取注解并拼接sql语句

    先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...

  10. java反射之获取所有方法及其注解(包括实现的接口上的注解),获取各种标识符备忘

    java反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...

随机推荐

  1. POJ - 3087:Shuffle'm Up (字符串模拟)

    一.内容 题意:给定2个字符串s1,s2,将2个字符串进行重组成S,规则是S2最下面拿一个,S1最下面拿1个,直到所有块都用完. 二.思路 用map记录下S串结果,若以前访问过这个串代表不可能有结果直 ...

  2. 复旦大学2020考研机试题-编程能力摸底试题(A-E)

    A.斗牛 给定五个0~9范围内的整数a1,a2,a3,a4,a5.如果能从五个整数中选出三个并且这三个整数的和为10的倍数(包括0),那么这五个整数的权值即为剩下两个没被选出来的整数的和对10取余的结 ...

  3. 图解 Promise 实现原理(三)—— Promise 原型方法实现

    本文首发于 vivo互联网技术 微信公众号 链接:  https://mp.weixin.qq.com/s/u8wuBwLpczkWCHx9TDt4Nw作者:Morrain Promise 是异步编程 ...

  4. HashMap非线程安全到底有什么问题

    HashMap是Java中常用的数据结构,用于存储键值对,并且提供了快速的查找和插入操作.下面挖掘一下HashMap内部的架构设计思维: 哈希函数的设计: HashMap使用哈希函数将键映射到数组索引 ...

  5. P1955【绿】

    这道题是标准的"离散化+并查集"模版题,通过这道题彻底理解了并查集,同时还意识到了我之前一直用map来实现离散化的方法其实是最简单但是最慢的方法,以这道题为例,map导致时间消耗有 ...

  6. Linux环境下如何查看Python版本号

    方法一.直接执行命令python,就可以查看python的版本信息. 退出用exit() 方法二.利用命令python -V,注意V要大写. 方法三.利用命令whereis python,注意wher ...

  7. RL 的探索策略 | Exploration for RL

    最近在草率地调研 RL 的 exploration. 这篇文章也比较草率,仅能起到辅助作用,不能代替读 review 或更精细的读 paper. 目录 0 总结写在最前面 1 主要参考资料 2 RL ...

  8. [转帖]安全技术和iptables防火墙

    目录 安全技术 Netfilter 防火墙工具介绍 iptables firewalld nftables iptables的组成概述 netfilter与iptables关系 iptables的四表 ...

  9. [转帖]SPEC2006

    安装步骤 # Ubuntu16.04 # 注意安装gFortran . ./install.sh . ./shrc 一般情况下经过以上步骤即可安装完毕,进行使用,注意需要执行shrc设置完环境变量以后 ...

  10. [转帖]Linux make: g++: Command not found

    https://www.cnblogs.com/kerrycode/p/4748606.html Linux使用make命令时遇到"make: g++: Command not found& ...