最近在学习java的反射和注解,实际情景中需要扫描某个包下的所有java类,然后使用类加载器加载类。

  基本思路,获得程序的路径扫描src下某个包内的子包和java类,实现也比较简单。

  运行环境:windows10+jdk1.8+eclipse

  直接贴代码

  

package org.test.scanner;

import java.io.File;
import java.util.ArrayList;
import java.util.List; /*
* date:2019-07-23
* */
public class PackageScanner {
private List<Class<?>> classes;
private String packagePath = null; /*
* 无参构造方法,内部调用带参的构造方法。
*
* @throw classNotFound
*
*/
public PackageScanner() throws ClassNotFoundException {
this("");
} /*
* 实现,调用fileScanner进行目录扫描和加载
*
* @param String 传入需要扫描的包
*
* @throw classNotFound
*/
public PackageScanner(String basePackage) throws ClassNotFoundException {
packagePath = System.getProperty("user.dir") + "\\src\\";
String filePath = packagePath + basePackage.replace('.', '\\');
classes = new ArrayList<Class<?>>();
fileScanner(new File(filePath));
} private void fileScanner(File file) throws ClassNotFoundException {
if (file.isFile() && file.getName().lastIndexOf(".java") == file.getName().length() - 5) {//5是".java"的长度
String filePath = file.getAbsolutePath();
String qualifiedName = filePath.substring(packagePath.length(), filePath.length() - 5).replace('\\', '.');
System.out.println(qualifiedName);
classes.add(Class.forName(qualifiedName));
return;
} else if (file.isDirectory()) {
for (File f : file.listFiles())
fileScanner(f);
}
} /*
* 得到加载到的类对象的List,返回的是ArrayList
*/
public List<Class<?>> getClasses() {
return this.classes;
}
}

  

这是一个简单的包扫描类,这里直接使用Class.forName()加载扫描到的类

我们可以看一下forName实现

public static Class<?> forName(String className) throws ClassNotFoundException {
return forName0(className, true, ClassLoader.getCallerClassLoader());
}

发现调用了ClassLoader.getCallerClassLoader() 

从名字上可以看出是得到调用类的类加载器,我们可以看一下它的实现

static ClassLoader getCallerClassLoader() {
// NOTE use of more generic Reflection.getCallerClass()
Class caller = Reflection.getCallerClass(3);
// This can be null if the VM is requesting it
if (caller == null) {
return null;
}
return caller.getClassLoader0();
}

关键一句: Reflection.getCallerClass(3)。

一直往上传递,直到获取到它的调用类,然后得到调用类的类加载器

其中 REflection.getCallerClass()的参数有:

0 和小于0  -   返回 Reflection类

1  -   返回自己的类

2  -    返回调用者的类 
3. 4. ....层层上传。

最后的目的就是谁调用这个类,调用类的类加载器就负责加载这个类。只有当它的加载类为null时,即没有任何加载器可用时,才使用getClassLoader0()这个native方法,这是启动类加载器的实现方法,如果不是java lib目录里的库,该类是不会被加载的。

通过学习java 的包扫描和类加载,我简单的了解了java类加载器的用法。

能力有限,如有错误请告知一声。

ps:学而不思则罔,思而不学则殆。

java扫描某个包下的所有java类并加载的更多相关文章

  1. Java语言Lang包下常用的工具类介绍_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...

  2. Java的静态代码块是否会在类被加载时自动执行?

    JAVA静态代码块会在类被加载时自动执行? 一.先看Java静态方法,静态变量 http://www.cnblogs.com/winterfells/p/7906078.html 静态代码块 在类中, ...

  3. 深入了解java虚拟机(JVM) 第十一章 类的加载

    一.类加载机制概述 虚拟机把描述类的数据从class文件加载到内存并对数据进行效验,解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制. 二.类加载的机制 类加载的过程 ...

  4. java中new一个对象的执行过程及类的加载顺序

    1,new一个对象时代码的执行顺序 (1)加载父类(以下序号相同,表明初始化是按代码从上到下的顺序来的) 1.为父类的静态属性分配空间并赋于初值 1.执行父类静态初始化块; (2)加载子类 2.为子类 ...

  5. Java程序设计19——类的加载和反射-Part-A

    1 本文概要 本章介绍Java类的加载.连接和初始化的深入知识,并重点介绍Java反射相关的内容.本章知识偏底层点,这些运行原理有助于我们更好的把我java程序的运行.而且Java类加载器除了根加载器 ...

  6. Java温故而知新(10)类的加载机制

    类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类加载机制的第二个目的是让程序能动态的控制类加载,比如热部署等,提高程序的灵活性 ...

  7. 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

    目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...

  8. [Java]类的生命周期(上)类的加载和连接[转]

    本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 类加载器,顾名思义,类加载器(class loader)用来加载 Java 类到 Java ...

  9. Java反射1——扫描某个包下的所有类

    1.从包package中获取所有的Class /** * 从包package中获取所有的Class * * @param pack * @return */ public static Set< ...

随机推荐

  1. BBS论坛 项目表分析

    一.项目表分析 from django.db import models from django.contrib.auth.models import AbstractUser # Create yo ...

  2. 【笔记篇】斜率优化dp(一) HNOI2008玩具装箱

    斜率优化dp 本来想直接肝这玩意的结果还是被忽悠着做了两道数论 现在整天浑浑噩噩无心学习甚至都不是太想颓废是不是药丸的表现 各位要知道我就是故意要打删除线并不是因为排版错乱 反正就是一个del标签嘛并 ...

  3. [JZOJ3233] 照片

    题目 题目大意 有一个\(01\)序列.给你一堆区间,每个区间中有且仅有一个\(1\)点. 问最多的\(1\)点个数. 思考历程 感觉这题特别经典,似乎在哪里见过,又好像没有见过. 一开始朝贪心方面想 ...

  4. 校园商铺-2Logback配置与使用-3验证配置

    1. 验证logback配置 1.1. 启动tomcat,得到CATALINA_BASE地址: 1.2 访问接口,查看日志 浏览器打开http://localhost:18080/o2o/supera ...

  5. luoguP2398 GCD SUM [gcd]

    题目描述 for i=1 to n for j=1 to n sum+=gcd(i,j) 给出n求sum. gcd(x,y)表示x,y的最大公约数. 输入输出格式 输入格式: n 输出格式: sum ...

  6. CF Round #427 (Div. 2) C. Star sky [dp]

    题目链接就长这样子? time limit per test 2 seconds memory limit per test 256 megabytes   Description The Carte ...

  7. EJB(Enterprise JavaBean)科普

    该文章是引用的,主要用于自己的学习,然后是记载免得忘记的时候到处乱找.结尾有引用地址. 到底EJB是什么?被口口相传的神神秘秘的,百度一番,总觉得没有讲清楚的,仍觉得一头雾水.百度了很久,也从网络的文 ...

  8. 关于C++ const 的全面总结 分类: ubuntu 2014-12-03 21:03 72人阅读 评论(0) 收藏

    C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助. Const 是C++中常用的类型修饰符,常类型是指使用类 ...

  9. Mac 解决硬盘插入不能写的问题

    软件解决 链接:https://pan.baidu.com/s/1H_zvPPpW0dp7aRUvjDnkQA  密码:8fit 有个NTFS的移动硬盘,默认Mac系统是不能写入,只能读取的,我们可以 ...

  10. CentOS升级GDB

    需要先安装ncurses-devel和texinfo 如果不安装ncurses-devel,编译会出错 如果不安装texinfo或者版本太低,安装会出错 1.yum install -y ncurse ...