java工具类 获取包下所有类

[java] view
plain
copy

  1. package com.threeti.util;
  2. import java.io.File;
  3. import java.io.FileFilter;
  4. import java.io.IOException;
  5. import java.net.JarURLConnection;
  6. import java.net.URL;
  7. import java.net.URLDecoder;
  8. import java.util.ArrayList;
  9. import java.util.Enumeration;
  10. import java.util.LinkedHashSet;
  11. import java.util.List;
  12. import java.util.Set;
  13. import java.util.jar.JarEntry;
  14. import java.util.jar.JarFile;
  15. /**
  16. * 类相关的工具类
  17. *
  18. * @author <a href="mailto:[email protected]">ohergal</a>
  19. *
  20. */
  21. public class ClassUtil {
  22. public static void main(String[] args) throws Exception{
  23. List<Class> classes = ClassUtil.getAllClassByInterface(Class.forName("com.threeti.dao.base.IGenericDao"));
  24. for (Class clas :classes) {
  25. System.out.println(clas.getName());
  26. }
  27. }
  28. /**
  29. * 取得某个接口下所有实现这个接口的类
  30. * */
  31. public static List<Class> getAllClassByInterface(Class c) {
  32. List<Class>  returnClassList = null;
  33. if(c.isInterface()) {
  34. // 获取当前的包名
  35. String packageName = c.getPackage().getName();
  36. // 获取当前包下以及子包下所以的类
  37. List<Class<?>> allClass = getClasses(packageName);
  38. if(allClass != null) {
  39. returnClassList = new ArrayList<Class>();
  40. for(Class classes : allClass) {
  41. // 判断是否是同一个接口
  42. if(c.isAssignableFrom(classes)) {
  43. // 本身不加入进去
  44. if(!c.equals(classes)) {
  45. returnClassList.add(classes);
  46. }
  47. }
  48. }
  49. }
  50. }
  51. return returnClassList;
  52. }
  53. /*
  54. * 取得某一类所在包的所有类名 不含迭代
  55. */
  56. public static String[] getPackageAllClassName(String classLocation, String packageName){
  57. //将packageName分解
  58. String[] packagePathSplit = packageName.split("[.]");
  59. String realClassLocation = classLocation;
  60. int packageLength = packagePathSplit.length;
  61. for(int i = 0; i< packageLength; i++){
  62. realClassLocation = realClassLocation + File.separator+packagePathSplit[i];
  63. }
  64. File packeageDir = new File(realClassLocation);
  65. if(packeageDir.isDirectory()){
  66. String[] allClassName = packeageDir.list();
  67. return allClassName;
  68. }
  69. return null;
  70. }
  71. /**
  72. * 从包package中获取所有的Class
  73. * @param pack
  74. * @return
  75. */
  76. public static List<Class<?>> getClasses(String packageName){
  77. //第一个class类的集合
  78. List<Class<?>> classes = new ArrayList<Class<?>>();
  79. //是否循环迭代
  80. boolean recursive = true;
  81. //获取包的名字 并进行替换
  82. String packageDirName = packageName.replace(‘.‘, ‘/‘);
  83. //定义一个枚举的集合 并进行循环来处理这个目录下的things
  84. Enumeration<URL> dirs;
  85. try {
  86. dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
  87. //循环迭代下去
  88. while (dirs.hasMoreElements()){
  89. //获取下一个元素
  90. URL url = dirs.nextElement();
  91. //得到协议的名称
  92. String protocol = url.getProtocol();
  93. //如果是以文件的形式保存在服务器上
  94. if ("file".equals(protocol)) {
  95. //获取包的物理路径
  96. String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
  97. //以文件的方式扫描整个包下的文件 并添加到集合中
  98. findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);
  99. } else if ("jar".equals(protocol)){
  100. //如果是jar包文件
  101. //定义一个JarFile
  102. JarFile jar;
  103. try {
  104. //获取jar
  105. jar = ((JarURLConnection) url.openConnection()).getJarFile();
  106. //从此jar包 得到一个枚举类
  107. Enumeration<JarEntry> entries = jar.entries();
  108. //同样的进行循环迭代
  109. while (entries.hasMoreElements()) {
  110. //获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
  111. JarEntry entry = entries.nextElement();
  112. String name = entry.getName();
  113. //如果是以/开头的
  114. if (name.charAt(0) == ‘/‘) {
  115. //获取后面的字符串
  116. name = name.substring(1);
  117. }
  118. //如果前半部分和定义的包名相同
  119. if (name.startsWith(packageDirName)) {
  120. int idx = name.lastIndexOf(‘/‘);
  121. //如果以"/"结尾 是一个包
  122. if (idx != -1) {
  123. //获取包名 把"/"替换成"."
  124. packageName = name.substring(0, idx).replace(‘/‘, ‘.‘);
  125. }
  126. //如果可以迭代下去 并且是一个包
  127. if ((idx != -1) || recursive){
  128. //如果是一个.class文件 而且不是目录
  129. if (name.endsWith(".class") && !entry.isDirectory()) {
  130. //去掉后面的".class" 获取真正的类名
  131. String className = name.substring(packageName.length() + 1, name.length() - 6);
  132. try {
  133. //添加到classes
  134. classes.add(Class.forName(packageName + ‘.‘ + className));
  135. } catch (ClassNotFoundException e) {
  136. e.printStackTrace();
  137. }
  138. }
  139. }
  140. }
  141. }
  142. } catch (IOException e) {
  143. e.printStackTrace();
  144. }
  145. }
  146. }
  147. } catch (IOException e) {
  148. e.printStackTrace();
  149. }
  150. return classes;
  151. }
  152. /**
  153. * 以文件的形式来获取包下的所有Class
  154. * @param packageName
  155. * @param packagePath
  156. * @param recursive
  157. * @param classes
  158. */
  159. public static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List<Class<?>> classes){
  160. //获取此包的目录 建立一个File
  161. File dir = new File(packagePath);
  162. //如果不存在或者 也不是目录就直接返回
  163. if (!dir.exists() || !dir.isDirectory()) {
  164. return;
  165. }
  166. //如果存在 就获取包下的所有文件 包括目录
  167. File[] dirfiles = dir.listFiles(new FileFilter() {
  168. //自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
  169. public boolean accept(File file) {
  170. return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
  171. }
  172. });
  173. //循环所有文件
  174. for (File file : dirfiles) {
  175. //如果是目录 则继续扫描
  176. if (file.isDirectory()) {
  177. findAndAddClassesInPackageByFile(packageName + "." + file.getName(),
  178. file.getAbsolutePath(),
  179. recursive,
  180. classes);
  181. }
  182. else {
  183. //如果是java类文件 去掉后面的.class 只留下类名
  184. String className = file.getName().substring(0, file.getName().length() - 6);
  185. try {
  186. //添加到集合中去
  187. classes.add(Class.forName(packageName + ‘.‘ + className));
  188. } catch (ClassNotFoundException e) {
  189. e.printStackTrace();
  190. }
  191. }
  192. }
  193. }
  194. }

[java] view
plain
copy

  1. 可以获取文件形式的也可以获取jar包形式的
时间: 2024-12-25 04:38:28

java工具类 获取包下所有类的相关文章

背水一战 Windows 10 (122) - 其它: 通过 Windows.System.Profile 命名空间下的类获取信息, 查找指定类或接口的所在程序集的所有子类和子接口

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 其它 通过 Windows.System.Profile 命名空间下的类获取信息 查找指定类或接口的所在程序集的所有子类和子接口 示例1.演示如何通过 Windows.System.Profile 命名空间下的类获取信息Information/ProfileInfo.xaml <Page x:Class="Windows10.Information.ProfileInfo" xmlns="htt

java getResourcesAsStream()如何获取WEB-INF下的文件流

getResourcesAsStream()来读取.properties文件,但是getResourcesAsStream()仅在java项目时能获取根目录的文件: 在web项目中,getResourcesAsStream()是获取classes目录的根路径 例如:文件在WEB-INF/conf/conf.properties. private Properties readConf(){ InputStream is = null; try{ //获取classes的路径,注意:由于转码的原因

通过项目下的包名获取包下的全部类

通过项目下的包名获取包下的全部类 public class GetClasses { public static Set<Class<?>> classes = new HashSet<>(); public static void main(String[] args) { GetAllClass("com.bihang.seayatest.nio"); System.out.println(classes.size()); } public st

java获取包下被指定注解的类

方案一: 采用reflections 框架(此框架依赖com.google.guava) 1.reflections框架地址:https://github.com/ronmamo/reflections 2.项目依赖 <dependency> <groupId>org.reflections</groupId> <artifactId>reflections</artifactId> <version>0.9.11</versi

代码片段,得到所有实现接口且在同包下的类

/** * 得到所有实现接口而且在同包下的的类 * @param aClass * @return * @throws IOException * @throws ClassNotFoundException */ public List<Class> getImplClass(Class aClass) throws IOException, ClassNotFoundException { List<Class> list = new ArrayList<>();

获取mdb下要素类FeatureClass,独立要素类,没有dataset获取要素类

转载自:http://blog.sina.com.cn/s/blog_6faf711d0100za4x.html 获取mdb数据库要素类的名称 整体思路如下:1.通过IWorkspace的Datasets属性获取工作空间中的所有Dataset对象(IEnumDataset)2.枚举EnumDataset,获取Dataset对象3.如果该Dataset是FeatureDataset4.QI到IFeatureClassContainer接口for(int i=0;i < pFClContainer.

使用javax.mail包下的类实现发送邮件工具类

IDEA 依赖: <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> 模板实体类: package springbootdemo.demo.entity; /** * @author * @date 2019/8/19 21:58 */ pu

通过Spring工具类获取classpath下的文件资源,解析xml

File cfgFile = ResourceUtils.getFile("classpath:test.txt"); 或者 org.springframework.core.io.Resource fileRource = new ClassPathResource("test.xml"); 获取文件:fileRource.getFile(); 获取文件流:fileRource.getInputStream(); 获取到xml:进行解析:例:<myXml&g

Java基础知识-java.util.concurrent包下常见类的使用

一,Condition 一个场景,两个线程数数,同时启动两个线程,线程A数1.2.3,然后线程B数4.5.6,最后线程A数7.8.9,程序结束,这涉及到线程之间的通信. public class ConditionTest { static class NumberWrapper { public int value = 1; } public static void main(String[] args) { //初始化可重入锁 final Lock lock = new ReentrantL