2013-03-20 54 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