使用 Java Constructor.newInstance(args) ,为什么会出现“错误的参数数量”?错误?

发布于 2024-11-26 02:39:59 字数 1351 浏览 0 评论 0原文

为什么会失败并出现错误:

Args are: -normi -nosplash
Exception in thread "main" java.lang.IllegalArgumentException: wrong 
     number of arguments
    at sun.reflect.NativeConstructorAccessorImpl
    .newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl
    .newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl
    .newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at TSStack.main(TSStack.java:14)

代码如下:

public static void main(String args[]) throws Exception {
    System.out.println("Args are: " + args[0]+ " " + args[1] );
        try {
            Constructor<Site> c = Site.class.getDeclaredConstructor();
            c.setAccessible(true); // use reflection to get access to  
                                      //this private constructor
            c.newInstance( (Object[])args );
          } catch (InvocationTargetException x) {
            x.printStackTrace();
          } catch (NoSuchMethodException x) {
            x.printStackTrace();
          } catch (InstantiationException x) {
            x.printStackTrace();
          } catch (IllegalAccessException x) {
            x.printStackTrace();
          }     
}

Why does this fail with the error :

Args are: -normi -nosplash
Exception in thread "main" java.lang.IllegalArgumentException: wrong 
     number of arguments
    at sun.reflect.NativeConstructorAccessorImpl
    .newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl
    .newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl
    .newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at TSStack.main(TSStack.java:14)

Here is the code:

public static void main(String args[]) throws Exception {
    System.out.println("Args are: " + args[0]+ " " + args[1] );
        try {
            Constructor<Site> c = Site.class.getDeclaredConstructor();
            c.setAccessible(true); // use reflection to get access to  
                                      //this private constructor
            c.newInstance( (Object[])args );
          } catch (InvocationTargetException x) {
            x.printStackTrace();
          } catch (NoSuchMethodException x) {
            x.printStackTrace();
          } catch (InstantiationException x) {
            x.printStackTrace();
          } catch (IllegalAccessException x) {
            x.printStackTrace();
          }     
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖乖公主 2024-12-03 02:39:59

当你有这一行时:

Site.class.getDeclaredConstructor();

你将返回一个不接受任何参数的 Site 类的构造函数,因为 getDeclaredConstructor 是一个可变参数函数,它接受以下参数列表作为参数:描述参数类型的 Class 对象。由于您没有列出任何内容,因此您将返回一个空构造函数。

来创建对象

c.newInstance( (Object[])args );

但是,您随后尝试通过调用This 尝试将 args 作为参数传递 。除非 args 为空,否则这会导致问题,因为您明确要求使用无参构造函数。

编辑:由于您正在寻找的构造函数(基于您的上述评论)想要接受可变数量的 String 作为参数,因此您想要寻找(我相信)接受 String 数组作为其参数的构造函数,因为内部可变参数函数是使用数组实现的。您可以按如下方式执行此操作:

Constructor<Site> c = Site.class.getDeclaredConstructor(String[].class);
c.setAccessible(true); // use reflection to get access to this private constructor
c.newInstance( (Object[])args );

但更重要的是,为什么要使用反射?仅仅这样写就更快、更干净、更安全。

new Site(args);

这使得 Java 能够静态地验证代码的安全性。

希望这有帮助!

When you have this line:

Site.class.getDeclaredConstructor();

You are getting back a constructor for the Site class that takes in no arguments, since getDeclaredConstructor is a variadic function that takes in as arguments a list of Class<?> objects describing the argument types. Since you didn't list anything, you're getting back a nullary constructor.

However, you then try creating the object by calling

c.newInstance( (Object[])args );

This tries passing in args as arguments. Unless args is empty, this will cause a problem, since you explicitly asked for a no-argument constructor.

EDIT: Since the constructor you're looking for (based on your above comment) wants to take in a variable number of Strings as an argument, you want to look for a constructor that (I believe) takes in an array of Strings as its argument, since internally variadic functions are implemented using arrays. You could do this as follows:

Constructor<Site> c = Site.class.getDeclaredConstructor(String[].class);
c.setAccessible(true); // use reflection to get access to this private constructor
c.newInstance( (Object[])args );

More importantly though, why are you using reflection at all? It's faster, cleaner, and safer just to write

new Site(args);

This allows Java to statically verify the safety of your code.

Hope this helps!

谁许谁一生繁华 2024-12-03 02:39:59

Site.class.getDeclaredConstructor() 将返回不带参数的默认构造函数,因此您必须向其传递一个空参数数组,这在您的示例中并非如此(否则您将在第一行失败与 System.out.println() )。

Site.class.getDeclaredConstructor() will return you default constructor with no arguments, so you must pass it an empty array of arguments which is not the case in your example (otherwise you would fail on the first line with System.out.println()).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文