2013-03-20 53 views
9

所以我有一个包含扩展JPanel的类,我想将它们动态添加为标签。在开始时我使用了一个工厂,我在其中注册了所有的类,并且它工作正常,但现在我想在不知道名称的情况下加载包中的所有类。我已经尝试了几件事情,包括Reflections library(我发现它很混乱),我无法让他们工作。我感谢任何帮助。如何获取包中的所有类名?

这是我的一种尝试:

public static void registerTab() { 
    String pkg = TabA.class.getPackage().getName(); 
    String relPath = pkg.replace('.', '/'); 

    URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); 
    if (resource == null) { 
     throw new RuntimeException("Unexpected problem: No resource for " 
       + relPath); 
    } 

    File f = new File(resource.getPath()); 

    String[] files = f.list(); 

    for (int i = 0; i < files.length; i++) { 

     String fileName = files[i]; 
     String className = null; 
     String fileNm = null; 

     if (fileName.endsWith(".class")) { 

      fileNm = fileName.substring(0, fileName.length() - 6); 
      className = pkg + '.' + fileNm; 
     } 

     if (className != null) { 

      if (!tabClasses.containsKey(className)) 
       tabClasses.put(fileNm, className); 
     } 
    } 
} 
+0

反射出了什么问题? – 2013-03-20 09:26:52

回答

50

这里是我公司开发找到一个包中的所有类的定制解决方案:

public class ClassFinder { 

    private static final char PKG_SEPARATOR = '.'; 

    private static final char DIR_SEPARATOR = '/'; 

    private static final String CLASS_FILE_SUFFIX = ".class"; 

    private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?"; 

    public static List<Class<?>> find(String scannedPackage) { 
     String scannedPath = scannedPackage.replace(PKG_SEPARATOR, DIR_SEPARATOR); 
     URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath); 
     if (scannedUrl == null) { 
      throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage)); 
     } 
     File scannedDir = new File(scannedUrl.getFile()); 
     List<Class<?>> classes = new ArrayList<Class<?>>(); 
     for (File file : scannedDir.listFiles()) { 
      classes.addAll(find(file, scannedPackage)); 
     } 
     return classes; 
    } 

    private static List<Class<?>> find(File file, String scannedPackage) { 
     List<Class<?>> classes = new ArrayList<Class<?>>(); 
     String resource = scannedPackage + PKG_SEPARATOR + file.getName(); 
     if (file.isDirectory()) { 
      for (File child : file.listFiles()) { 
       classes.addAll(find(child, resource)); 
      } 
     } else if (resource.endsWith(CLASS_FILE_SUFFIX)) { 
      int endIndex = resource.length() - CLASS_FILE_SUFFIX.length(); 
      String className = resource.substring(0, endIndex); 
      try { 
       classes.add(Class.forName(className)); 
      } catch (ClassNotFoundException ignore) { 
      } 
     } 
     return classes; 
    } 

} 

然后,只需使用:

List<Class<?>> classes = ClassFinder.find("com.package"); 
+0

谢谢!我会试试看。 – Tareq 2013-03-20 09:33:48

+0

它返回一个空列表。我像这样使用它'List > cls = ClassFinder.find(TabA.class.getPackage()。getName());' – Tareq 2013-03-20 09:54:45

+0

@Tareq是在你的项目的JAR中或直接在* classes *文件夹中的TabA ?该解决方案仅适用于第二种情况。 – sp00m 2013-03-20 09:57:18