JavaSE阶段配置文件解析、反射以及注解综合小练习
JavaSE阶段配置文件解析、反射以及注解综合小练习
练习要求
先创建一个项目wzry,在项目中创建一个resource源文件夹,在该文件夹下,有一个
web.properties配置文件。该配置文件内容如下:
package=cn #package是key,值是cn指的是包
annotantion=HeroType #HeroType是值,是一个英雄类型注解
请解析这个配置文件,然后将package作为扫描【遍历硬盘上cn目录下的所有文件夹、文件】的目录包,
扫描包下所有java类,将所有HeroType注解的值是"力量型"英雄的类,调用beGoodAt()方法。
通过分析题意,我们将本题分为三个部分
1.解析配置文件,获得包名及注解名
2.获得注解类对应的字节码文件
3.通过反射找出符合题意的类,并调用方法
首先在main方法中解析properties类型的配置文件
此处采用的是类加载器的方式,通过当前类的加载器获取
另外也可以通过当前线程获取,方法很多,不再赘述了
public class HeroTest2 {public static Class hero = null;public static void main(String[] args) throws Exception {// 解析配置文件,获得包名和注解名Properties p = new Properties();ClassLoader classLoader = HeroTest2.class.getClassLoader();//获取当前类加载器String pa = null;// 声明包名String ann = null;// 声明注解名try(/** 2. 通过类加载器的方式 1.同当前类的加载器获取1.当前类.class.getClassLoader();// 获取当前类加载器2.classLoader.getResourceAsStream("文件路径/文件名");//通过类加载器获取流对象,如果是源文件夹,直接文件名*/InputStream is = classLoader.getResourceAsStream("web.properties");//获取当前类加载器并获取流BufferedInputStream bis = new BufferedInputStream(is);){p.load(bis);// load方法解析配置文件pa = p.getProperty("package");// 获得包名cnann = p.getProperty("annotantion");// 获取注解名HeroType} catch (FileNotFoundException e) {System.out.println("文件没有找到异常!");e.printStackTrace();} catch (IOException e) {System.out.println("IO异常!");e.printStackTrace();}// 获得项目的绝对路径File file = new File(pa);String paPath = file.getAbsolutePath();
// System.out.println(paPath);//E:\Java_software\eclipse-jee-neon-2\eclipse_workspace\wzry\cnString path = paPath.substring(0, (paPath.length()-pa.length()-1));
// System.out.println(path);//E:\Java_software\eclipse-jee-neon-2\eclipse_workspace\wzryFile dir = new File(path);getHero(dir,pa,ann);//调用获取注解对象字节码文件方法getStrengthHero(dir,pa);//调用获取对象方法}
获取到配置文件中的包名及注解名之后,便可以实现对对应的包进行遍历,查找符合题意的java文件
其中获取注解类字节码文件的代码如下:
public static Class getHero(File dir,String pa,String ann) throws Exception {if (dir.isFile() && dir.getName().equals(ann + ".java") && dir.getAbsolutePath().contains(pa)) {String path = dir.getAbsolutePath();
// System.out.println(path);
// // E:\Java_software\eclipse-jee-neon-2\eclipse_workspace\wzry\src\cn\itsource\hero\HeroType.javapath = path.substring(path.indexOf(pa));
// System.out.println(path);
// // cn\itsource\hero\HeroType.javapath = path.replace("\\",".").replaceAll(".java", "");
// System.err.println(path);
// // cn.itsource.hero.HeroTypehero = Class.forName(path);} else if (dir.isDirectory()) {File[] listFiles = dir.listFiles();for (File file : listFiles) {getHero(file,pa,ann);}}return null;}
通过递归方法遍历文件夹,找到符合配置文件中注解名的类并获取到其字节码文件。
接下来只剩通过class.getAnnotation()方法获取到每个java文件的注解内容,再将其与题目中的所需类型进行比对即可。
public static void getStrengthHero(File dir,String pa) throws Exception {if (dir.isFile() && dir.getName().endsWith(".java") && !dir.getName().contains("HeroType") && dir.getAbsolutePath().contains(pa)) {String path = dir.getAbsolutePath();
// System.out.println(path);path = path.substring(path.indexOf(pa)).replace("\\",".").replaceAll(".java", "");
// System.err.println(path);// 通过文件名获取每一个对应的字节码对象Class c = Class.forName(path);if (c.getAnnotation(hero) != null) {String annString = c.getAnnotation(hero).toString();
// System.out.println(annString);/** @cn.itsource.hero.HeroType(type=智力型)@cn.itsource.hero.HeroType(type=敏捷型)@cn.itsource.hero.HeroType(type=力量型)*/if (annString.contains("力量型")) {// 通过当前匹配上的字节码对象去获取对象中的普通方法 beGoodAt()Method method = c.getMethod("beGoodAt");// 执行非static修饰的beGoodAt()方法, 是通过当前method对象调用执行方法 invoke()// Object invoke(Object obj, Object... args) //非static需要对象// 3.先通过字节码对象获取一个构造方法对象,再去用newInstance()创建对象method.invoke(c.getConstructor().newInstance());}}} else if (dir.isDirectory()) {File[] listFiles = dir.listFiles();for (File file : listFiles) {getStrengthHero(file,pa);}}}
通过反射的方式获取类中的方法、构造方法,并创建对象调用方法即可完成题目要求。
附上题目已给的几个已知类:
Hero类
/*** 英雄类* 抽象基类*/
public abstract class Hero {/*** 擅长的能力*/public abstract void beGoodAt();
}
注解类
/*** 英雄类型*/
@Target(ElementType.TYPE)//只有一个值,且属性的名字是value可以省略
@Retention(RetentionPolicy.RUNTIME)
public @interface HeroType {String type();
}
@HeroType(type="智力型")
public class Master extends Hero {@Overridepublic void beGoodAt() {System.out.println("烧死你.....");}}
@HeroType(type="敏捷型")
public class Shooter extends Hero {@Overridepublic void beGoodAt() {System.out.println("射你.....");}}
@HeroType(type="力量型")
public class Warrior extends Hero {@Overridepublic void beGoodAt() {System.out.println("砍死你.....");}}
以上即为JavaSE初学阶段关于注解、反射以及配置文件解析的综合小练习,仅供参考。
JavaSE阶段配置文件解析、反射以及注解综合小练习相关推荐
- 黑马就业班(01.JavaSE Java语言基础-11.Java基础加强)——基础加强:Junit单元测试、反射、注解
1.Junit单元测试 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要写代码的.关注程序具体的执行流程. Junit使用:白盒测试 步骤: ...
- JavaSE——单元测试、反射、注解、动态代理
文章目录 单元测试 单元测试概述 单元测试快速入门 单元测试常用注解 反射 反射概述 反射获取类对象 反射获取构造器对象 反射获取成员变量对象 反射获取方法对象 反射的作用-绕过编译阶段为集合添加数据 ...
- Java基础13:反射与注解详解
Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...
- JavaSE阶段笔记
JavaSE 一.Java编程基础 ①.数据类型 基本数据类型 数值型(int,long) 字符型(char) 布尔型(boolean) 引用数据类型 类(class) 接口(interface) 数 ...
- 反射、注解、动态代理、JDK8新特性
反射.注解.动态代理.JDK8新特性 第一章.反射 1.类的加载 源文件--通过javac编译-->字节码文件---通过Java命令(通过ClassLoader)--->JVM运行字节码文 ...
- JavaSE——第23章 反射reflection
JavaSE--第23章 反射reflection(老师:韩顺平) 文章目录 JavaSE--第23章 反射reflection(老师:韩顺平) 23.2 反射机制 23.2.1 Java refle ...
- 基础加强:反射和注解
目录 一.Junit单元测试 1.什么是单元测试 2.Junit的使用步骤 3.单元测试中其它四个注解 二.反射 1.类的加载 2.什么是反射 3.反射在实际开发中的应用 4.反射中万物皆对象的概念 ...
- 【Java】Junit、反射和注解的笔记
1 Junit 黑盒测试:不需要写代码,给输入值,看程序输出是否符合期望 白盒测试:需要写代码,关注程序具体的执行流程 Junit -> 白盒测试 步骤 定义一个测试类(测试用例) [命名:类名 ...
- junit单元测试,反射,注解
今日内容 1. Junit单元测试 2. 反射 3. 注解 Junit单元测试: * 测试分类:1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值.2. 白盒测试:需要写代码的.关注程 ...
最新文章
- Matlab读写二进制文件
- github php面试题,GitHub - johnsong261510/php_interviews: PHP 面试题汇总、剑指 Offer PHP 代码实现版本...
- java 控件内布局_Java开发桌面程序学习(二)————fxml布局与控件学习
- 玩转OpenVswitch(一):端口与网桥
- 概括鸿蒙系统的优势,从开发语言分析鸿蒙系统有何优势
- 【小项目关键技术二】UGV电机编码测速
- Issue 140: Tweet
- C++成员函数的内存分配问题
- 集群(三)——haproxy+nginx搭建web集群
- 优秀博客-前端博客(转)
- C盘pagefile.sys不可删除,解决磁盘占用太满的问题
- python修改zabbix中的ip
- SLAM中直接法分类及对应的项目
- windows系统bat批处理 windows 关机,重启,锁定,休眠,注销
- php beanstalkd使用,如何用PHP设置Beanstalkd
- STM32-正弦波可调(50HZ~20KHZ可调、峰峰值0~3.3V可调)
- Pytorch关于高维tensor的dim上操作的理解--以cosine_similarity的dim参数为例
- flutter 应用 adb shell input swipe 命令失效
- 黄反词测试,接口监控
- ruby on rails_如何将刺激添加到Ruby on Rails应用程序