簡體   English   中英

Java中的動態類加載(枚舉)

[英]Dynamic Class Loading in Java (Enumeration)

我有一個問題,我希望使用反射在運行時生成一組類中的一個的實例。 但是,我遇到了麻煩。 我想讓所有涉及的類都注冊自己,這樣就可以從GUI中選擇合適的類。 我可以在每個文件中使用靜態代碼塊來提供整潔的OO解決方案。 但是,java類加載器在需要時專門加載類,因此如果尚未使用所需的類,則不會注冊它。

如果沒有直接提供靜態名稱列表,或者運行底層的類/ java文件(無論如何打包到jar中都會破壞),有沒有辦法強制加載某些包的類?

基本上,我希望能夠從指定的超類添加新類,而無需更改/添加任何其他代碼。

澄清一下,你的問題不是關於“Java中的動態類加載”,而是關於動態類枚舉 - 你知道如何加載類,你只是不知道你想要什么類。

谷歌快速推出了這個頁面: http//forums.sun.com/thread.jspa?threadID = 341935&start = 0&tstart = 0

從該頁面開始,這里有一些應該有效的示例代碼:

public static Class[] getClasses(String pckgname)
        throws ClassNotFoundException {
    ArrayList<Class> classes = new ArrayList<Class>();
    // Get a File object for the package
    File directory = null;
    try {
        ClassLoader cld = Thread.currentThread().getContextClassLoader();
        if (cld == null) {
            throw new ClassNotFoundException("Can't get class loader.");
        }
        String path = '/' + pckgname.replace('.', '/');
        URL resource = cld.getResource(path);
        if (resource == null) {
            throw new ClassNotFoundException("No resource for " + path);
        }
        directory = new File(resource.getFile());
    } catch (NullPointerException x) {
        throw new ClassNotFoundException(pckgname + " (" + directory
                + ") does not appear to be a valid package");
    }
    if (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
                classes.add(Class.forName(pckgname + '.'
                        + files[i].substring(0, files[i].length() - 6)));
            }
        }
    } else {
        throw new ClassNotFoundException(pckgname
                + " does not appear to be a valid package");
    }
    Class[] classesA = new Class[classes.size()];
    classes.toArray(classesA);
    return classesA;
}

Spring Framework基於注釋進行組件掃描。

例如,查看ClassPathScanningCandidateComponentProvider類。 您可以基於接口/基類執行相同的操作,它應該適用於所有LOCAL類。 對於java中的所有類,無法執行此操作。

Class.forName(“class name here”);

你將擁有一個帶有類名的String變量。 假設您有一個字符串列表,其中包含您要加載的所有類名(並使用靜態代碼塊自動注冊:

for(String className:classesToBeLoaded)Class.forName(className);

通過這個例子:

public class MainClass {

  public static void main(String[] args){

    ClassLoader classLoader = MainClass.class.getClassLoader();

    try {
        Class aClass = classLoader.loadClass("com.jenkov.MyClass");
        System.out.println("aClass.getName() = " + aClass.getName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

}

如果您的類在文件系統中的jar中有可能(這可能聽起來很荒謬,但我看過從ldaps加載的類)

因此,如果您的類位於jar中的文件系統中,您可以執行以下操作:

下面的偽java:

  String classPath = System.getClassPath(); 
  String [] classPathParts = classpath.split(";"); // or :

  String [] allTheClasses = []

  for each ( file  in classPathParts ) {
      if( file is directory ) {
           allTheClasses.addAll( file.contents );
      } else if ( file is ".jar" ) {
           allTheClasses.addAll( getZippedNamesFrom( file ) );

      }
 }

 // At this point you would have all the classes in the array ( list ) .

 String [] packageNames = {"a.b.c", "d.e.f" };
 for each ( String  clazzName in allTheClasses ) {
       if ( packageNames.contains( clazzName.getPackageName() ) ) {
           Class.forName( clazzName ); // load it and have the static block run
           // Or run it your self
       }
 }

 // End of the story.

我很久以前就做過類似的事情。

我用不到一秒鍾就可以使用這種方法加載大約70k +類名。 在我的情況下,我動態地尋找大約10個類,所以整個過程花了我大約1.1秒。

我建議將所有“動態”類放入一個包中。 掃描該目錄以獲取每個文件名,然后在Class.forName()中使用它來加載和注冊每個類。

我昨天剛問了一個類似的問題,得到了一些很好的反饋。

從Java中的Variable創建新類

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM