在现在好多应用场景中,我们需要得到某个包名下面所有的类, 包括我们自己在src里写的java类和一些第三方提供的jar包里的类,那么怎么来实现呢?
今天带大家来完成这件事。
先分享代码:
1.这个类是一个抽象类,对类的处理交给用户,所以就有了dealClass的抽象方法。
package com.mec.packscanner.core; import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile; public abstract class PackageScanner {
public PackageScanner() {} public abstract void dealClass(Class<?> klass); //扫描一般的包。
private void scanPackage(String packageName,File currentfile) {
File[] filelist = currentfile.listFiles(new FileFilter() {
//FileFilter是文件过滤器,源代码只写了一个accapt的抽象方法。
@Override
public boolean accept(File pathName) {
if(pathName.isDirectory()) { //判断是否是目录
return true;
}
return pathName.getName().endsWith(".class");
}
}); for(File file:filelist) {
if(file.isDirectory()) {
scanPackage(packageName + "." + file.getName(),file);
}else {
String fileName = file.getName().replace(".class", "");
String className = packageName + "." + fileName;
try {
Class<?> klass = Class.forName(className);//取出所有的类
if(klass.isAnnotation() //不扫描注解类、枚举类、接口和八大基本类型。
||klass.isEnum()
||klass.isInterface()
||klass.isPrimitive()) {
continue;
}
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
} //扫描jar包方法。
private void scanPackage(URL url) throws IOException {
JarURLConnection urlConnection = (JarURLConnection) url.openConnection();
JarFile jarfile = urlConnection.getJarFile();
Enumeration<JarEntry> jarEntries = jarfile.entries();
while(jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarName = jarEntry.getName();
if(!jarName.endsWith(".class")) {
continue;
}
String className = jarName.replace(".class", "").replaceAll("/", "."); try {
Class<?> klass = Class.forName(className);
if (klass.isAnnotation()
|| klass.isInterface()
|| klass.isEnum()
|| klass.isPrimitive()) {
continue;
}
dealClass(klass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} //用类名扫描
public void packageScan(Class<?> klass) {
packageScan(klass.getPackage().getName());
} //用包名进行扫描
public void packageScan(String packageName) {
String packOpperPath = packageName.replace(".","/"); //线程上下文类加载器得到当前的classpath的绝对路径.(动态加载资源)
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
try {
//(Thread.currentThread().getContextClassLoader().getResource(""))
//(来得到当前的classpath的绝对路径的URI表示法。)
Enumeration<URL> resources = classloader.getResources(packOpperPath);
while(resources.hasMoreElements()) {
//先获得本类的所在位置
URL url = resources.nextElement(); //url.getProtocol()是获取URL的HTTP协议。
if(url.getProtocol().equals("jar")) {
//判断是不是jar包
scanPackage(url);
}else {
//此方法不会自动将链接中的非法字符转义。
//而在File转化成URI的时候,会将链接中的特殊字符如#或!等字符进行编码。
File file = new File(url.toURI());
if(!file.exists()) {
continue;
}
scanPackage(packageName,file);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
这个是抽象类,对于扫描,我们只提供扫描的工具,而定义抽象方法是往外接,通过使用者的使用来决定用类名还是包名。
对于jar包的扫描,可以进JarURLConnection类和JarFile类的源码中可以理解。
2.定义测试类,它是扫描jar包的:
package com.mec.packscanner.test; import com.mec.packscanner.core.PackageScanner; public class Test { public static void main(String[] args) {
new PackageScanner() { @Override
public void dealClass(Class<?> klass) {
System.out.println(klass.getName()); }
}.packageScan("com.mec.xml_view.core");;
} }
结果:
从结果我们可以看出把jar包中的每一个class都输出了,匿名内部类都被扫描出来了。
我们来看看普通包的结果吧:
package com.mec.packscanner.test; import com.mec.packscanner.core.PackageScanner; public class Test { public static void main(String[] args) {
new PackageScanner() { @Override
public void dealClass(Class<?> klass) {
System.out.println(klass.getName()); }
}.packageScan("com.mec.server_client.core");;
} }
对普通的包也是,这个例子除了接口,其他的都被扫描出来了。
若有漏洞,请指正!感谢您的阅读。
Java中的包扫描(工具)的更多相关文章
-
java 中的包概念
Java 中的包package, 就是电脑中的文件夹.我们平时在工作中,文件太多时,都会新建文件夹进行分类管理,java 中的包也是类似的道理,当我们的类太多时,也需要进行分类管理,这时我们就会把类文 ...
-
Java中带包(创建及引用)的类的编译
Java中带包(创建及引用)的类的编译与调试 java源程序的编译大家都知道,也就是cmd中到源文件所在目录下javac **.java即可,当程序中有包声明还能简简单单的直接javac **.jav ...
-
理解Java中【包】的概念
Java中用package关键字定义一个包,下面通过几个实验,理解Java中的包的概念和作用. 实验1:先看一个无包的情形 在G盘下新建一个Test.java,如图1: 写下面这些代码 <spa ...
-
java中的包以及内部类的介绍
1:形式参数和返回值的问题(理解) (1)形式参数: 类名:需要该类的对象 抽象类名:需要该类的子类对象 接口名:需要该接口的实现类对象 (2)返 ...
-
java中的包有那些 ???
java.util工具包java.sql数据库包java.io输入输出流包java.net网络包java.lang基础包这些是基本的包,还有一些其他的例如集合,反射等的工具包,你可以去查一下java ...
-
Java中的包含义
JAVA提供了强大的应用程序接口,既JAVA类库.他包含大量已经设计好的工具类,帮助程序员进行字符串处理.绘图.数学计算和网络应用等方面的工作.下面简单介绍JAVA核心类库中常用的组建包. 1.jav ...
-
java中的Arrays这个工具类你真的会用吗
Java源码系列三-工具类Arrays 今天分享java的源码的第三弹,Arrays这个工具类的源码.因为近期在复习数据结构,了解到Arrays里面的排序算法和二分查找等的实现,收益匪浅,决定研读 ...
-
Java中,包的概念、常量、静态成员、继承
新建包:左上角-新建-包 命名规则(通常从大到小,方便整合不容易冲突) 例如:com.itnba.maya.test package必须在最顶行,之前不能再有其他代码 使用包: 快捷方式:使用包中的 ...
-
Java中的包
包:定义包用package关键字. 1:对类文件进行分类管理. 2:给类文件提供多层名称空间. 如果生成的包不在当前目录下,需要最好执行classpath,将包所在父目录定义到classpath变量中 ...
随机推荐
-
spring事务详解(转载+高亮)
spring提供的事务管理可以分为两类:编程式的和声明式的.编程式的,比较灵活,但是代码量大,存在重复的代码比较多:声明式的比编程式的更灵活.编程式主要使用transactionTemplate.省略 ...
-
在CMD窗口中使用javac和java命令进行编译和执行带有包名的具有继承关系的类
一.背景 最近在使用记事本编写带有包名并且有继承关系的java代码并运行时发现出现了很多错误,经过努力一一被解决,今天我们来看一下会遇见哪些问题,并给出解决办法. 二.测试过程 1.父类代码 pack ...
-
mysql安装启动教程(两种方法)
mysql安装启动: 方法一(简单版): cmd进入mysql安装的bin目录:mysqld.exe –install net start mysql 服务启动(或者选择计算机->(右键)管理 ...
-
[bzoj1195] [hnoi2006] 最短母串
本题是一个经典的状压dp问题,在紫书中有着加强版的例题. 本题的难度主要体现在:如何输出字符串字典序最小. 为了解决这个问题,我们有两种常用方案: 1) 我们可以采用bfs输出路径的方法,使用+1来输 ...
-
[2017-07-18]logstash配置示例
提醒 /etc/logstash/conf.d/下虽然可以有多个conf文件,但是Logstash执行时,实际上只有一个pipeline,它会将/etc/logstash/conf.d/下的所有con ...
-
Alpha冲刺Day7
Alpha冲刺Day7 一:站立式会议 今日安排: 由林静和周静平共同完成企业风险分级展示这一模块的分级列表展示,该模块主要提供企业自查风险的条件查询功能 由黄腾飞和张梨贤共同完成企业风险分级展示的分 ...
-
android JNI调用机制
JNI的出现使得开发者既可以利用Java语言跨平台.类库丰 富.开发便捷等特点,又可以利用Native语言的高效. JNI是JVM实现中的一部分,因此Native语言和Java代码都运行在JVM的宿主 ...
-
UVA1660 电视网络 Cable TV Network
题目地址:UVA1660 电视网络 Cable TV Network 枚举两个不直接连通的点 \(S\) 和 \(T\) ,求在剩余的 \(n-2\) 个节点中最少去掉多少个可以使 \(S\) 和 \ ...
-
《算法》第五章部分程序 part 6
▶ 书中第五章部分程序,包括在加上自己补充的代码,非确定性有穷自动机(NFA),grep 命令(利用 NFA 匹配) ● 非确定性有穷自动机(NFA) package package01; impor ...
-
数学图形(2.26) 3D曲线结
我收集的几种曲线结 knot(huit) #http://www.mathcurve.com/courbes3d/noeuds/noeudenhuit.shtml vertices = 1000 t ...