2016-03-31 13 views
2

ここでは、invoke()はエラー:java.lang.ClassNotFoundException: class HelloWorld$Fooでエラーが発生しています。私も.classを直接使用する代わりに文字列.class.toString()を得ることに頼らざるを得ませんでした。クラスのマップを反復して呼び出します

toString()コールを避けていない場合は、このメソッドを呼び出せますか?

import java.lang.reflect.Constructor; 
import java.util.HashMap; 
import java.util.Map; 

public class HelloWorld{ 

    public static void main(String []args){ 
     Map<String, Class> myMap = new HashMap<String, Class>(); 
     myMap.put("foo", Foo.class); 
     myMap.put("bar", Bar.class); 

     try { 
      for(String name : myMap.keySet()){ 
       Class<?> clazz = Class.forName(myMap.get(name).toString()); // do I need to go through string at all? 
       Object foobar = clazz.newInstance(); 
       System.out.println("name: " + name + " goes " + foobar.getClass().getMethod("chirp").invoke(foobar)); 
      } 
     } catch (Throwable e) { 
      System.err.println(e); 
     } 
    } 
    public abstract class Foobar { 
     abstract String chirp(); 
    } 
    public class Foo extends Foobar { 
     public String chirp() { return "chirp-chirp!"; } 
    } 
    public class Bar extends Foobar { 
     public String chirp() {return "woof-woof!"; } 
    } 
} 

編集:完成答え:

import java.lang.reflect.Constructor; 
import java.util.HashMap; 
import java.util.Map; 

public class HelloWorld{ 

    public static void main(String []args){ 
     Map<String, Class> myMap = new HashMap<String, Class>(); 
     myMap.put("foo", Foo.class); 
     myMap.put("bar", Bar.class); 

     try { 
     for(Map.Entry<String, Class> entry : myMap.entrySet()){ 
      Class<?> clazz = entry.getValue();     
      Object foobar = clazz.getConstructor( HelloWorld.class).newInstance(new HelloWorld());; 
      System.out.println("name: " + entry.getKey() + " goes " + clazz.getMethod("chirp").invoke(foobar)); 
     } 
    } catch (Throwable e) { 
      System.err.println(e); 
     } 
    } 
    public abstract class Foobar { 
     abstract String chirp(); 
    } 
    public class Foo extends Foobar { 
     public String chirp() { return "chirp-chirp!"; } 
    } 
    public class Bar extends Foobar { 
     public String chirp() {return "woof-woof!"; } 
    } 
} 

答えて

3

FooHelloWorldの内部クラスであるため、HelloWorldのインスタンスによって作成されなければなりません。代わりにpublic static class Foo ...を試してください。

Fooが内部クラス(つまり、staticではなく)である必要がある場合は、対応するコンストラクタを呼び出す必要があります。

Foo.class.getConstructor( HelloWorld.class).newInstance(new HelloWorld()); 

上記の例は、clazz.getConstructor(...)を使用している可能性があることに注意してください。ただし、この場合、Barが静的​​な「内部」クラスである場合、そのクラスのコンストラクタは存在しません。したがって、クラスが異なる場合は、どのコンストラクタが利用可能かをチェックする必要があります。

Class<?> clazz = myMap.get(name);でも十分です。

また、ループ内でルックアップをする必要はありません。マップのエントリセットを繰り返し処理するだけです。また、clazzのインスタンスを作成するので、foobar.getClass()を呼び出す必要はありませんが、clazzを直接使用することができます。

for(Map.Entry<String, Class> entry : myMap.entrySet()){ 
    Class<?> clazz = entry.getValue();     
    Object foobar = ...; 
    System.out.println("name: " + entry.getKey() + " goes " + clazz.getMethod("chirp").invoke(foobar)); 
} 
+0

ありがとうございます。 –

関連する問題