在Java中获取包内的类文件数组

我需要一个包含在我的Java源代码包中的所有类文件的Class []。

我无法一次性找到标准方法。 如果有人可以编写一个函数来获取该列表将非常有用。

Class[] myClasses = yourfunction(); // Return a list of class inside a source package in the currently working project in java 

我能够使用普通的文件I / O和搜索机制来解决这个问题。 您可以在此处查看答案。

 private static List getClassesForPackage(Package pkg) { String pkgname = pkg.getName(); List classes = new ArrayList(); // Get a File object for the package File directory = null; String fullPath; String relPath = pkgname.replace('.', '/'); //System.out.println("ClassDiscovery: Package: " + pkgname + " becomes Path:" + relPath); URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); //System.out.println("ClassDiscovery: Resource = " + resource); if (resource == null) { throw new RuntimeException("No resource for " + relPath); } fullPath = resource.getFile(); //System.out.println("ClassDiscovery: FullPath = " + resource); try { directory = new File(resource.toURI()); } catch (URISyntaxException e) { throw new RuntimeException(pkgname + " (" + resource + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...", e); } catch (IllegalArgumentException e) { directory = null; } //System.out.println("ClassDiscovery: Directory = " + directory); if (directory != null && directory.exists()) { // Get the list of the files contained in the package String[] files = directory.list(); for (int i = 0; i < files.length; i++) { // we are only interested in .class files if (files[i].endsWith(".class")) { // removes the .class extension String className = pkgname + '.' + files[i].substring(0, files[i].length() - 6); //System.out.println("ClassDiscovery: className = " + className); try { classes.add(Class.forName(className)); } catch (ClassNotFoundException e) { throw new RuntimeException("ClassNotFoundException loading " + className); } } } } else { try { String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); JarFile jarFile = new JarFile(jarPath); Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String entryName = entry.getName(); if (entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) { //System.out.println("ClassDiscovery: JarEntry: " + entryName); String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); //System.out.println("ClassDiscovery: className = " + className); try { classes.add(Class.forName(className)); } catch (ClassNotFoundException e) { throw new RuntimeException("ClassNotFoundException loading " + className); } } } } catch (IOException e) { throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e); } } return classes; } 

没有在所有虚拟机上尝试这一点,但在最近的Oracle虚拟机上有一个更短的方法:

 Enumeration resources = Thread.currentThread().getContextClassLoader().getResources("package/name/with/slashes/instead/dots"); while (resources.hasMoreElements()) { URL url = resources.nextElement(); System.out.println(url); System.out.println(new Scanner((InputStream) url.getContent()).useDelimiter("\\A").next()); } 

这将打印出包中资源的名称,因此您可以在它们上使用getResource(...) 。 调用url.getContent()将返回sun.net.www.content.text.PlainTextInputStream的实例,它是VM特定的类。