2012-03-21 103 views
0

我試圖從exchanges.jar文件加載的類文件(不執行任何通用的接口),並將其存儲在一個ArrayList 以前,我加載的.class文件(它實現了一個通用的接口)使用如何從一個jar文件加載類,並將其存儲在一個ArrayList

package edu.uh.cs.assign2; 

import java.io.File; 
import java.util.ArrayList; 

import edu.uh.cs.iexchangeservices.IExchange; 

public class ExchangeManager { 
    private ArrayList<IExchange> exchangeList = new ArrayList<IExchange>(); 

    public ArrayList<IExchange> findClasses() throws Exception { 

     File classDirectoryPath = new File(Thread.currentThread() 
       .getContextClassLoader() 
       .getResource("exchangeservices".replace('.', '/')).getFile()); 

     return loadExchangeClasses(classDirectoryPath); 
    } 

    public ArrayList<IExchange> loadExchangeClasses(File classDirectoryPath) 
      throws Exception { 

     if (!classDirectoryPath.exists()) 
      throw new LoadExchangesException("path not found"); 

     String[] exchangeClasses = classDirectoryPath.list(); 

     for (String exchangeClass : exchangeClasses) { 

      if (exchangeClass.endsWith(".class")) { 
       Object object = (IExchange) Class.forName(
         "exchangeservices" 
           + '.' 
           + exchangeClass.substring(0, 
             exchangeClass.length() - 6)) 
         .newInstance(); 

       if (object instanceof IExchange) 
        exchangeList.add((IExchange) object); 
      } 
     } 
     return exchangeList; 
    } 

} 
+0

我可能是錯的,但是,這聽起來不像是很好的編程習慣。你想用這個類的數組列表來做什麼? – 2012-03-21 00:20:47

+0

@user所有你需要做的,從一個罐子加載類是把罐子您的類路徑:'java命令; myjar.jar',有沒有爲什麼你覺得你需要加載在運行時類的理由? – 2012-03-21 00:20:52

+0

這些文件實際上是在一個jar文件中嗎?你的代碼看起來像是在磁盤上尋找它們...? – Adam 2012-03-21 00:20:56

回答

7

我會假設你想要做的是加載了一套位於JAR文件或任何其他URL類別,然後目錄返回一個包含這些類對象的列表。

我的建議是:

  • 使用類java.util.jar.JarFile閱讀你的罐子中的所有條目。
  • 遍歷條目,如果給定項屬於一類(其名稱的「.class」結尾),那麼你加載類,並把它添加到加載類的列表。

有點像這樣:

JarFile jar = new JarFile(jarFile); 
for(JarEntry entry: Collections.list(jar.entries())){ 
    if(entry.getName().endsWith(".class")){ 
    String className = entry.getName().replace("/", ".").replace(".class",""); 
    foundClasses.add(loader.loadClass(className)); 
    } 
} 

對於加載的目的,你可以使用包含您的JAR文件中的java.net.URLClassLoader

有點像這個

File jarFile = new File("./jedis.jar"); 
URLClassLoader loader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()}); 

您將結束在foundClasses列表中的所有加載的類。

在另一方面,如果你確切地知道你要加載的類,那麼應該是URLClassLoader足以解決問題。

File jarFile = new File("./jedis.jar"); 
URLClassLoader loader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()}); 
foundClasses.add(loader.loadClass("jedi.academy.ObiWan")); 
foundClasses.add(loader.loadClass("jedi.academy.Luke")); 
foundClasses.add(loader.loadClass("jedi.academy.Anakin")); 

如果你想,這二次的類加載器是獨立的系統類加載器的一定要設置父類加載器實例化的URLClassLoader時爲null:

URLClassLoader loader = new URLClassLoader(new URL[]{jarFile.toURI().toURL()}, null); 
+0

謝謝你回答我的問題。我想知道我是否可以讓這些類實現一個通用接口。因爲我必須迭代類的列表,我想存儲實現特定接口的特定類。 – user1282182 2012-03-21 21:17:35

+0

@ user1282182如果這回答了您的問題,請將其標記爲這樣。 – 2012-05-05 14:17:04

+0

@Edwin Dalorzo Sry發現類型是什麼類?它是一個類還是其他的東西? – marzie 2015-09-16 09:35:57

相關問題