Java遍历包中所有类

[java]  view plain  copy
  1. package com.itkt.mtravel.hotel.util;  
  2.   
  3. import java.io.File;  
  4. import java.net.URL;  
  5. import java.net.URLClassLoader;  
  6. import java.util.ArrayList;  
  7. import java.util.Enumeration;  
  8. import java.util.List;  
  9. import java.util.jar.JarEntry;  
  10. import java.util.jar.JarFile;  
  11.   
  12. public class PackageUtil {  
  13.   
  14.     public static void main(String[] args) throws Exception {  
  15.         String packageName = "com.wang.vo.request.hotel";  
  16.         // List classNames = getClassName(packageName);  
  17.         List classNames = getClassName(packageName, false);  
  18.         if (classNames != null) {  
  19.             for (String className : classNames) {  
  20.                 System.out.println(className);  
  21.             }  
  22.         }  
  23.     }  
  24.   
  25.     /** 
  26.      * 获取某包下(包括该包的所有子包)所有类 
  27.      * @param packageName 包名 
  28.      * @return 类的完整名称 
  29.      */  
  30.     public static List getClassName(String packageName) {  
  31.         return getClassName(packageName, true);  
  32.     }  
  33.   
  34.     /** 
  35.      * 获取某包下所有类 
  36.      * @param packageName 包名 
  37.      * @param childPackage 是否遍历子包 
  38.      * @return 类的完整名称 
  39.      */  
  40.     public static List getClassName(String packageName, boolean childPackage) {  
  41.         List fileNames = null;  
  42.         ClassLoader loader = Thread.currentThread().getContextClassLoader();  
  43.         String packagePath = packageName.replace(".""/");  
  44.         URL url = loader.getResource(packagePath);  
  45.         if (url != null) {  
  46.             String type = url.getProtocol();  
  47.             if (type.equals("file")) {  
  48.                 fileNames = getClassNameByFile(url.getPath(), null, childPackage);  
  49.             } else if (type.equals("jar")) {  
  50.                 fileNames = getClassNameByJar(url.getPath(), childPackage);  
  51.             }  
  52.         } else {  
  53.             fileNames = getClassNameByJars(((URLClassLoader) loader).getURLs(), packagePath, childPackage);  
  54.         }  
  55.         return fileNames;  
  56.     }  
  57.   
  58.     /** 
  59.      * 从项目文件获取某包下所有类 
  60.      * @param filePath 文件路径 
  61.      * @param className 类名集合 
  62.      * @param childPackage 是否遍历子包 
  63.      * @return 类的完整名称 
  64.      */  
  65.     private static List getClassNameByFile(String filePath, List className, boolean childPackage) {  
  66.         List myClassName = new ArrayList();  
  67.         File file = new File(filePath);  
  68.         File[] childFiles = file.listFiles();  
  69.         for (File childFile : childFiles) {  
  70.             if (childFile.isDirectory()) {  
  71.                 if (childPackage) {  
  72.                     myClassName.addAll(getClassNameByFile(childFile.getPath(), myClassName, childPackage));  
  73.                 }  
  74.             } else {  
  75.                 String childFilePath = childFile.getPath();  
  76.                 if (childFilePath.endsWith(".class")) {  
  77.                     childFilePath = childFilePath.substring(childFilePath.indexOf("\\classes") + 9, childFilePath.lastIndexOf("."));  
  78.                     childFilePath = childFilePath.replace("\\", ".");  
  79.                     myClassName.add(childFilePath);  
  80.                 }  
  81.             }  
  82.         }  
  83.   
  84.         return myClassName;  
  85.     }  
  86.   
  87.     /** 
  88.      * 从jar获取某包下所有类 
  89.      * @param jarPath jar文件路径 
  90.      * @param childPackage 是否遍历子包 
  91.      * @return 类的完整名称 
  92.      */  
  93.     private static List getClassNameByJar(String jarPath, boolean childPackage) {  
  94.         List myClassName = new ArrayList();  
  95.         String[] jarInfo = jarPath.split("!");  
  96.         String jarFilePath = jarInfo[0].substring(jarInfo[0].indexOf("/"));  
  97.         String packagePath = jarInfo[1].substring(1);  
  98.         try {  
  99.             JarFile jarFile = new JarFile(jarFilePath);  
  100.             Enumeration entrys = jarFile.entries();  
  101.             while (entrys.hasMoreElements()) {  
  102.                 JarEntry jarEntry = entrys.nextElement();  
  103.                 String entryName = jarEntry.getName();  
  104.                 if (entryName.endsWith(".class")) {  
  105.                     if (childPackage) {  
  106.                         if (entryName.startsWith(packagePath)) {  
  107.                             entryName = entryName.replace("/"".").substring(0, entryName.lastIndexOf("."));  
  108.                             myClassName.add(entryName);  
  109.                         }  
  110.                     } else {  
  111.                         int index = entryName.lastIndexOf("/");  
  112.                         String myPackagePath;  
  113.                         if (index != -1) {  
  114.                             myPackagePath = entryName.substring(0, index);  
  115.                         } else {  
  116.                             myPackagePath = entryName;  
  117.                         }  
  118.                         if (myPackagePath.equals(packagePath)) {  
  119.                             entryName = entryName.replace("/"".").substring(0, entryName.lastIndexOf("."));  
  120.                             myClassName.add(entryName);  
  121.                         }  
  122.                     }  
  123.                 }  
  124.             }  
  125.         } catch (Exception e) {  
  126.             e.printStackTrace();  
  127.         }  
  128.         return myClassName;  
  129.     }  
  130.   
  131.     /** 
  132.      * 从所有jar中搜索该包,并获取该包下所有类 
  133.      * @param urls URL集合 
  134.      * @param packagePath 包路径 
  135.      * @param childPackage 是否遍历子包 
  136.      * @return 类的完整名称 
  137.      */  
  138.     private static List getClassNameByJars(URL[] urls, String packagePath, boolean childPackage) {  
  139.         List myClassName = new ArrayList();  
  140.         if (urls != null) {  
  141.             for (int i = 0; i < urls.length; i++) {  
  142.                 URL url = urls[i];  
  143.                 String urlPath = url.getPath();  
  144.                 // 不必搜索classes文件夹  
  145.                 if (urlPath.endsWith("classes/")) {  
  146.                     continue;  
  147.                 }  
  148.                 String jarPath = urlPath + "!/" + packagePath;  
  149.                 myClassName.addAll(getClassNameByJar(jarPath, childPackage));  
  150.             }  
  151.         }  
  152.         return myClassName;  
  153.     }  
  154. }  

由于我们并不确定jar包生成时采用的哪种方式,如果采用默认生成jar包的方式,那我们通过Thread.currentThread().getContextClassLoader().getResource()是获取不到的,因此我增加了从所有jar包中搜索提供的包域名,这样功能就完善了很多。

那么就此关于“如何遍历包中所有类”就结束了,PackageUtil这个类的功能还有些少,不排除日后进一步完善的可能,如果大家关于这个util有什么新的需求或者建议,随时欢迎大家提出。发现bug的,也请及时通知我以便改进。

转自:http://blog.csdn.net/wangpeng047/article/details/8206427

你可能感兴趣的:(Java)