IllegalArgumentException: неправильное количество аргументов в Java Constructor.newInstance () - PullRequest
6 голосов
/ 28 февраля 2011

Рассмотрим следующий код:

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

Что с ним не так?Я получаю следующее исключение:

Исключение в потоке "main" java.lang.IllegalArgumentException: неверное число аргументов в sun.reflect.NativeConstructorAccessorImpl.newInstance0 (собственный метод) в sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:39) в sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:27) в java.lang.reflect.Constructor.newInstance (Constructor.javap5).java: 10)

Ответы [ 2 ]

23 голосов
/ 28 февраля 2011

Ваш 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());

По сути этосмесь обработки varargs и ковариации массива: (

0 голосов
/ 28 февраля 2011

Вы можете использовать опцию 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());
    }
}
...