3

new Class();250を超えるサブクラスがあり、それらで作成されたインスタンスが必要です。そこに座って、 250回コイアンドペーストすることはできません。とにかくReflectionを使用してクラスのインスタンスを作成することはありますか?インスタンスを作成するときにコンストラクターは必要ありません。ありがとう。

4

4 に答える 4

3

私は本当にあなたを理解していませんが、推測しようとします(テストされていません):

public class Test {
    public static void main(String[] args) {
        Class[] classes = new Class[]{Class1.class, Class2.class, Class3.class};
        for (Class cls : classes) {
            Object myObject = cls.newInstance();
            -------^^^^^^^^-------
        }
    }
}

新しいクラス インスタンスの作成を参照してください。

編集: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String )

Class.forName("mypackage.MyClassname");
于 2012-09-21T22:14:14.597 に答える
2

まず、すべてのサブクラスを取得する必要があります。私は自分でテストしていませんが、その特定の答えは正当に思えます。

次に、クラスを反復処理し、渡す必要があるコンストラクターのパラメーターがある場合は、 Class.newInstance(引数なしのコンストラクター) またはClass.getConstructorandを使用してインスタンスを作成します。Constructor.newInstance最終的なコードは次のようになります。

Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeType>> subTypes = 
        reflections.getSubTypesOf(SomeType.class);
Set<SomeType> someTypes = new HashSet<SomeType>(subTypes.size());
for (Class<? extends SubType> subType : subTypes) {
    someTypes.add(subType.newInstance());
}
// Do something with someTypes here

これにより、サブクラスが取得され、それらが繰り返され、それぞれのインスタンスが作成されます。ここには、私が何もしていないいくつかの例外があります。また、いくつかのキャストを行う必要がある場合もあります (ただし、そうする必要はないと思います)。

編集:上記の私の答えは、明らかに偽のクラスの読み込みを引き起こします。代わりに、次のように一連のサブクラスを作成します。

Reflections reflections = new Reflections(...); //see in other use cases
Set<String> subTypeFqns = reflections.getStore().getSubTypesOf(SomeClass.class.getName());
Set<Class<?>> subTypes = new HashSet<Class<?>>();
for (String fqn : subTypeFqns) {
    subTypes.add(Class.forName(fqn));
}

次に、これらの行:

for (Class<? extends SubType> subType : subTypes) {
    someTypes.add(subType.newInstance());
}

これになる:

for (Class<?> subType : subTypes) {
    someTypes.add((SomeType) subType.newInstance());
}
于 2012-09-21T22:18:44.413 に答える
0

次のように実行できます。

Class instantiableClass = Class.forName("package.subpackage.ClassName");
Object instance = instantableClass.newInstance();

クラスにデフォルトのコンストラクターまたは public zero args コンストラクターしかない場合にのみ機能します。必要に応じて、コードをループ、一般化、または再現することができます。

より一般的な解決策については、これが不可能な理由を理解するのに役立ちます。知っているクラス、クラスの名前を知っているクラス、任意のソースからクラスの名前にアクセスできるクラス、または任意の方法でそのような最小限の情報を提供されたクラスで、やりたいことが何でもできます。

しかし、そのクラスの知識がなければ、ほとんど不可能です。現在のクラスパスですべてのクラスを探してから、特定のクラスに準拠しているかどうかを継承ツリーで確認する必要があります。

于 2012-09-21T22:16:18.737 に答える
0

これは、パッケージのすべてのクラスをロードし、新しいインスタンスを作成し、それらをハッシュマップに配置するコードのチャンクです (すべてのクラスは Commande から継承されます)。

    this.actions = new HashMap<String, Commande>();

    ServletContext sc = this.getServletContext();

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL res = classLoader.getResource(COMMAND_DIRECTORY);
    File[] list = new File(res.getFile()).listFiles();
    String className = "";
    for (File f : list) {
        className = f.getName().replaceAll(".class$", "");
        try {
            Class<?> classe = Class.forName("org.commandes." + className);
            if (classe.getSuperclass() == Commande.class) {
                Commande c = (Commande) classe.newInstance();
                this.actions.put(c.getName(), c);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

ここで、COMMAND_DIRECTORY は私にとっては org/commandes です。

これが正しい方法かどうかはわかりませんが、コマンド設計パターン (プラグインのような実装) をサーブレットに実装する唯一の方法です。

于 2012-09-21T22:16:44.973 に答える