7

次のコードを検討してください。

public class StartUp {

    public StartUp(String[] test){}

    public static void main(String[] args) throws Exception{
        Constructor cd = StartUp.class.getConstructor(String[].class);
        System.out.println(cd.newInstance(new String[]{}).toString());
    }
}

どうしたの?次の例外が発生します。

スレッド「メイン」の例外 java.lang.IllegalArgumentException: sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) の sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) の引数の数が間違っています。 newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at com.test.StartUp.main(StartUp.java:10)

4

2 に答える 2

22

あなたString[]は、空の配列である単一の引数としてではなく、暗黙的Object[]に引数の空の配列に変換され、取り込まれています。これを試して:

Object arg = new String[0];
System.out.println(cd.newInstance(arg).toString());

また

System.out.println(cd.newInstance(((Object)new String[0]).toString());

または、コンパイラが配列を作成する必要がまったくないようにすることもできます。

System.out.println(cd.newInstance(new Object[] { new String[0] }).toString());

基本的に、これは可変引数の処理と配列の共分散の混合です:(

于 2011-02-28T13:53:00.043 に答える
-1

dp4j verbose オプションを使用して質問に答え、必要な正しいリフレクション コードを取得できます。

$ vim ReflectedAcces.java
 class StartUp {

    private StartUp(String[] test){}

}

public class ReflectedAcces{

        @com.dp4j.InjectReflection
    public static void main(String[] args) throws Exception{
                StartUp su = new StartUp(new String[]{});
                System.out.println(su.toString());
    }

}
 

$ javac -cp dp4j-1.0-jar-with-dependencies.jar -Averbose=true ReflectedAcces.java 
...
ReflectedAcces.java:10: Note: 
class StartUp {
    
    private StartUp(String[] test) {
    }
}
public class ReflectedAcces {
    
    public ReflectedAcces() {
        super();
    }
    
    @com.dp4j.InjectReflection()
    public static void main(String[] args) java.lang.ClassNotFoundException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.lang.NoSuchMethodException, java.lang.reflect.InvocationTargetException, java.lang.InstantiationException {
        final java.lang.reflect.Constructor startUpConstructor = Class.forName("StartUp").getDeclaredConstructor(.java.lang.String[].class);
        startUpConstructor.setAccessible(true);
        StartUp su = (.StartUp)startUpConstructor.newInstance(new .java.lang.Object[1][]{new String[]{}});
        System.out.println(su.toString());
    }
}
于 2011-02-28T15:57:23.673 に答える