java 反射,接口、类层级查找

写道
package org.com.test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

@SuppressWarnings("all")
public class ClassUtils {
private static Class searchClassObj = null;

// 给一个接口,返回这个接口的所有实现类
public static List<Class> getAllClassByInterfaceFromPackage(String className, String jarPath) {
List<Class> returnClassList = new ArrayList<Class>(); // 返回结果
// 如果不是一个接口,则不做处理

// String packageName = c.getPackage().getName(); // 获得当前的包名
try {
List<Class> allClass = getPackageClasses(jarPath, className); // 获得当前包下以及子包下的所有类
if (null != searchClassObj) {
// 判断是否是同一个接口
for (Class c : allClass) {
if (searchClassObj.isAssignableFrom(c)) { // 判断是不是一个接口
if (!searchClassObj.equals(c)) { // 本身不加进去
returnClassList.add(c);
}
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return returnClassList;
}

// 给一个接口,返回这个接口的所有实现类
public static List<Class> getAllClassByInterfaceFromJar(String className, String jarPath) {
List<Class> returnClassList = new ArrayList<Class>(); // 返回结果
try {
List<Class> allClass = getJarClasses(jarPath, className); // 获得当前包下以及子包下的所有类
if (null != searchClassObj) {
// 判断是否是同一个接口
for (int i = 0; i < allClass.size(); i++) {
if (searchClassObj.isAssignableFrom(allClass.get(i))) { // 判断是不是一个接口
if (!searchClassObj.equals(allClass.get(i))) { // 本身不加进去
returnClassList.add(allClass.get(i));
}
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return returnClassList;
}

/**
* 获得包中所有类,必须在类的搜索路径中
*
* @param packageName
* 包名称
* @param className
* 要查找的类名称
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
private static List<Class> getPackageClasses(String packageName, String className)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName, className));
}
return classes;
}

/**
* 查找包中的类 ,此时包名必须在类的搜索路径中,否则会抛出ClasseNotFoundException异常。
*
* @param directory
* 包转转化后的file对象
* @param packageName
* 包名称
* @param className
* 类名称
* @return
* @throws ClassNotFoundException
*/
private static List<Class> findClasses(File directory, String packageName, String className)
throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName(), className));
//System.out.println(file.getName());
} else if (file.getName().endsWith(".class")) {
//System.out.println(file.getName());
Class tempObj =
Class.forName(packageName
+ '.' + file.getName().substring(0, file.getName().length() - 6));
if (file.getName().equals(className + ".class")) {
searchClassObj = tempObj;
}
classes.add(tempObj);
}
}
return classes;
}

/**
* 加载jar中的类文件
* @param jarPath jar的路径,可以不在类的搜索路径中
* @param className 类名称
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
private static List<Class> getJarClasses(String jarPath, String className)
throws ClassNotFoundException, IOException{
List<Class> result = new Vector<Class>();
JarFile jarFile = new JarFile(jarPath);
Enumeration files = jarFile.entries();
while (files.hasMoreElements()) {
JarEntry entry = (JarEntry) files.nextElement();
String entryName = entry.getName();
if (entryName.endsWith(".class")) {
URL url = new URL("jar:file:"+jarPath+"!/"+entryName);
URLClassLoader urlLoader = new URLClassLoader(new URL[]{url});
String classNamePackage = entryName.substring(0,entryName.lastIndexOf(".")).replaceAll("/", ".");
Class c = Class.forName(classNamePackage);
//System.out.println(c.getName());
result.add(c);
if (entryName.substring(entryName.lastIndexOf(File.separator) + 1).equals(className
+ ".class")) {
searchClassObj = c;
}
}
}
return result;
}

public static void main(String args[]) {
List<Class> checkClasses = ClassUtils.getAllClassByInterfaceFromJar("IMessageProcessThread", "/data/ocean/Resources/Src/windin.ocean/deploy/lib/windin.ocean.thirdnews.server.jar");
if(null != checkClasses && checkClasses.size()>0){
for(Class c : checkClasses){
System.out.println(c.getName());
}
}
}
}

 最近想看看java中如何在一个包中或者在一个jar中去查找某个类或者查找实现某个接口的类。然后实例话 。原理很简单如果是一个包的话就当作目录处理。如果是一个jar的话在jar中按照目录进行处理。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值