java 获取 包 所有类_java工具类 获取包下所有类

该博客主要介绍了Java工具类`ClassUtil`,用于扫描指定包及其子包下的所有类,并找出实现了特定接口的类。方法包括`getAllClassByInterface`用于获取实现指定接口的类列表,以及`getClasses`和`getPackageAllClassName`用于获取包下的类名。这些工具方法对于理解和操作Java项目中的类结构非常有用。
摘要由CSDN通过智能技术生成

extends:http://blog.csdn.net/jdzms23/article/details/17550119

package com.threeti.util;

import java.io.File;

import java.io.FileFilter;

import java.io.IOException;

import java.net.JarURLConnection;

import java.net.URL;

import java.net.URLDecoder;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.LinkedHashSet;

import java.util.List;

import java.util.Set;

import java.util.jar.JarEntry;

import java.util.jar.JarFile;

/**

* 类相关的工具类

*

* @author ohergal

*

*/

public class ClassUtil {

public static void main(String[] args) throws Exception{

List classes = ClassUtil.getAllClassByInterface(Class.forName("com.threeti.dao.base.IGenericDao"));

for (Class clas :classes) {

System.out.println(clas.getName());

}

}

/**

* 取得某个接口下所有实现这个接口的类

* */

public static List getAllClassByInterface(Class c) {

List  returnClassList = null;

if(c.isInterface()) {

// 获取当前的包名

String packageName = c.getPackage().getName();

// 获取当前包下以及子包下所以的类

List> allClass = getClasses(packageName);

if(allClass != null) {

returnClassList = new ArrayList();

for(Class classes : allClass) {

// 判断是否是同一个接口

if(c.isAssignableFrom(classes)) {

// 本身不加入进去

if(!c.equals(classes)) {

returnClassList.add(classes);

}

}

}

}

}

return returnClassList;

}

/*

* 取得某一类所在包的所有类名 不含迭代

*/

public static String[] getPackageAllClassName(String classLocation, String packageName){

//将packageName分解

String[] packagePathSplit = packageName.split("[.]");

String realClassLocation = classLocation;

int packageLength = packagePathSplit.length;

for(int i = 0; i< packageLength; i++){

realClassLocation = realClassLocation + File.separator+packagePathSplit[i];

}

File packeageDir = new File(realClassLocation);

if(packeageDir.isDirectory()){

String[] allClassName = packeageDir.list();

return allClassName;

}

return null;

}

/**

* 从包package中获取所有的Class

* @param pack

* @return

*/

public static List> getClasses(String packageName){

//第一个class类的集合

List> classes = new ArrayList>();

//是否循环迭代

boolean recursive = true;

//获取包的名字 并进行替换

String packageDirName = packageName.replace('.', '/');

//定义一个枚举的集合 并进行循环来处理这个目录下的things

Enumeration dirs;

try {

dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);

//循环迭代下去

while (dirs.hasMoreElements()){

//获取下一个元素

URL url = dirs.nextElement();

//得到协议的名称

String protocol = url.getProtocol();

//如果是以文件的形式保存在服务器上

if ("file".equals(protocol)) {

//获取包的物理路径

String filePath = URLDecoder.decode(url.getFile(), "UTF-8");

//以文件的方式扫描整个包下的文件 并添加到集合中

findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);

} else if ("jar".equals(protocol)){

//如果是jar包文件

//定义一个JarFile

JarFile jar;

try {

//获取jar

jar = ((JarURLConnection) url.openConnection()).getJarFile();

//从此jar包 得到一个枚举类

Enumeration entries = jar.entries();

//同样的进行循环迭代

while (entries.hasMoreElements()) {

//获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件

JarEntry entry = entries.nextElement();

String name = entry.getName();

//如果是以/开头的

if (name.charAt(0) == '/') {

//获取后面的字符串

name = name.substring(1);

}

//如果前半部分和定义的包名相同

if (name.startsWith(packageDirName)) {

int idx = name.lastIndexOf('/');

//如果以"/"结尾 是一个包

if (idx != -1) {

//获取包名 把"/"替换成"."

packageName = name.substring(0, idx).replace('/', '.');

}

//如果可以迭代下去 并且是一个包

if ((idx != -1) || recursive){

//如果是一个.class文件 而且不是目录

if (name.endsWith(".class") && !entry.isDirectory()) {

//去掉后面的".class" 获取真正的类名

String className = name.substring(packageName.length() + 1, name.length() - 6);

try {

//添加到classes

classes.add(Class.forName(packageName + '.' + className));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

return classes;

}

/**

* 以文件的形式来获取包下的所有Class

* @param packageName

* @param packagePath

* @param recursive

* @param classes

*/

public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List> classes){

//获取此包的目录 建立一个File

File dir = new File(packagePath);

//如果不存在或者 也不是目录就直接返回

if (!dir.exists() || !dir.isDirectory()) {

return;

}

//如果存在 就获取包下的所有文件 包括目录

File[] dirfiles = dir.listFiles(new FileFilter() {

//自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)

public boolean accept(File file) {

return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));

}

});

//循环所有文件

for (File file : dirfiles) {

//如果是目录 则继续扫描

if (file.isDirectory()) {

findAndAddClassesInPackageByFile(packageName + "." + file.getName(),

file.getAbsolutePath(),

recursive,

classes);

}

else {

//如果是java类文件 去掉后面的.class 只留下类名

String className = file.getName().substring(0, file.getName().length() - 6);

try {

//添加到集合中去

classes.add(Class.forName(packageName + '.' + className));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

}

}

Java 扫描包下所有类(包括jar包)

package com.MyUtils.file; [java] view plain copy import java.io.File; import java.io.FileFilter; imp ...

java 查找指定包下的类

package com.jason.test; import java.io.File; import java.io.IOException; import java.io.UnsupportedE ...

java&period;io 包下的类有哪些 &plus; 面试题

java.io 包下的类有哪些 + 面试题 IO 介绍 IO 是 Input/Output 的缩写,它是基于流模型实现的,比如操作文件时使用输入流和输出流来写入和读取文件等. IO 分类 传统的 IO ...

Tomcat - 怎么控制某个类或者包下的日志打印级别

问题与分析 Tomcat是使用自己的日志实现tomcat-juli.jar来打印日志信息的,日志会被打印到catalina.out里,除去你在项目里自己使用的日志框架外,由System.out,Sys ...

Java-File类获取目录下文件名-遍历目录file&period;listFiles

package com.hxzy.IOSer;import java.io.*;/*File 类获取功能 * List * ListFile * */public class Demo06 { pub ...

【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

java 移动开发获取多级下拉框json数据的类和mobile-select-area插件

我这里以行政区划做例子 //这个类是把数据库中的行政区划转化为json格式的data @SuppressWarnings("rawtypes")public class XzqhL ...

Java并发编程之java&period;util&period;concurrent包下常见类的使用

一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public class Co ...

随机推荐

asp&period;net设置默认打开页面,Web&period;config,defaultDocument

The web.config file can be used to set a default document, or list of default documents for your web ...

Selenium用户扩展

Selenium用户扩展 这很容易扩展Selenium IDE加入自定义操作,断言和定位,策略,这是通过添加方法,在JavaScript的帮助下Selenium 对象原型.在启动时,Selenium会 ...

Eclipse的Debug调试技巧

作为开发人员,掌握开发环境下的调试技巧十分有必要.我们在编写java程序的过程中,经常会遇到各种莫名其妙的问题,为了检测程序是哪里出现问题,经常需要增加日志,看变量的值,这样调试很麻烦.假设我每天花费 ...

Java多线程操作局部变量与全局变量

在这篇文章里,我们首先阐述什么是同步,不同步有什么问题,然后讨论可以采取哪些措施控制同步,接下来我们会仿照回顾网络通信时那样,构建一个服务器端的"线程池",JDK为我们提供了一个很 ...

http协议、web服务器、并发服务器(下)

Web静态服务器-5-非堵塞模式 单进程非堵塞模型 import socket import time def main(): tcp_socket_server = socket.socket(so ...

使用Comparable接口自定义排序

Employee: package textq; /** * 调用接口Comparable排序 * @author Administrator * */ public class Employee i ...

&lbrack;pat&rsqb;数素数

时间限制:1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 令Pi表示第i个素数.现任给两个正整数M <= N &lt ...

项目冲刺Second

Second Sprint 1.各个成员今日完成的任务 蔡振翼:完成管理员界面 谢孟轩:完成用户界面 林凯:完成登录界面 肖志豪:完成主界面 吴文清:创建数据库 刘华强:完成连接数据库,编写查询语句 ...

ASP&period;NET Core使用Elasticsearch记录NLog日志

ASP.NET Core使用Elasticsearch记录NLog日志 1.新建一个 ASP.NET Core项目 2.安装Nuge包 运行:Install-Package NLog.Web.AspN ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值