2012-03-21 6 views
0

exchangees.jarファイルからクラスファイル(共通のインタフェースを実装していないクラス)をロードし、arraylistに格納しようとしています 以前、私は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

私が間違っている可能性が、この良いプログラミング実践のようには聞こえません。あなたはこの授業の練習家と何をしたいですか? –

+0

@user jarからクラスをロードするために必要なことは、クラスパスにjarを入れることです: 'java -cp。; myjar.jar'は、実行時にクラスをロードする必要があると感じる理由です? –

+0

ファイルは実際にjarファイルに入っていますか?あなたのコードはディスク上でそれらを探しているようです...? – Adam

答えて

7

を使用してディレクトリから(共通インタフェースを実装).classファイルは、私が何をやりたいが、その後、JARファイル、または任意の他のURLにあるクラスのセットをロードすることであると仮定しますロードこれらのクラスオブジェクトを含むリストを返します。

私の推奨事項は次のようになります。

  • はあなたのjarファイル内のすべてのエントリを読み取るために、クラスjava.util.jar.JarFileを使用してください。
  • エントリを反復処理し、あるエントリがクラスに属している(その名前が ".class"で終わっている)場合は、そのクラスをロードしてロードされたクラスのリストに追加します。あなたのjarファイルを含むjava.net.URLClassLoaderを使用することができますロードの目的で

    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)); 
        } 
    } 
    

    :ややこのよう

ややこの

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

+0

@ user1282182これがあなたの質問に答えた場合は、そのようにマークしてください。 –

+0

@Edwin Dalorzo Sry foundClassesのタイプは何ですか?それはクラスか他のものですか? – marzie

関連する問題