Java 没有参数的 getConstructor

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27579783/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:38:13  来源:igfitidea点击:

getConstructor with no parameters

javagetconstructor

提问by user3086720

I can't seem to use getConstructorfor constructors with no parameters.

我似乎不能getConstructor用于没有参数的构造函数。

I keep getting the following exception:

我不断收到以下异常:

java.lang.NoSuchMethodException: classname.<init>()

Here is the code:

这是代码:

interface InfoInterface {
    String getClassName();
    String getMethodName();
    String getArgument();
}

class asa implements InfoInterface {
    @Override
    public String getClassName() {
        return ("jeden");
    }
    @Override
    public String getMethodName() {
        return ("metoda");
    }
    @Override
    public String getArgument() {
        return ("krzyk");
    }
}

class Jeden {
    Jeden() {
        System.out.println("konstruktor");
    }

    public void Metoda(String s) {
        System.out.println(s);
    }
}

class Start {
    public static void main(String[] argv) {
        if (argv.length == 0) {
            System.err.println("Uzycie programu: java Start nazwa_klasy nazwa_klasy2...");
            return;
        }

        try {
            for (int x = 0; x < argv.length; x++) {
                Class<?> c = Class.forName(argv[x]);
                InfoInterface d = (InfoInterface) c.newInstance();
                String klasa = d.getClassName();
                String metoda = d.getMethodName();
                String argument = d.getArgument();

                Class<?> o = Class.forName(klasa);
                // o.newInstance();

                Constructor<?> oCon = o.getConstructor();
                System.out.println("ASD");
                Class<?> p = (Class<?>) oCon.newInstance();
            }
        } catch (Exception e) {
            System.out.println(e);
        }

    }
}

o.newInstance();prints "konstruktor"without problems.

o.newInstance();打印"konstruktor"没有问题。

采纳答案by fge

The problem is clear when you read the javadoc of .getConstructor():

当您阅读以下javadoc.getConstructor()时,问题就很清楚

Returns a Constructor object that reflects the specified publicconstructor of the class represented by this Class object.

返回一个 Constructor 对象,该对象反映了此 Class 对象表示的类的指定公共构造函数。

Emphasis mine.

强调我的。

In your code, the constructor is not public!

在您的代码中,构造函数不是公开的!

Example:

例子:

// Note: class is NOT public -- its default constructor won't be either
final class Test
{
    public static void main(final String... args)
        throws NoSuchMethodException
    {
        // throws NoSuchMethodException
        Test.class.getConstructor();
    }
}

Obligatory link to an SO answerwhich also gives the JLS reference. In particular, note that the default constructor has the same access modifier as the class.

SO 答案的强制性链接,该答案也提供了 JLS 参考。特别要注意的是,默认构造函数与类具有相同的访问修饰符。

回答by wassgren

It seems as if your class provides a constructor that is NOTa default constructor. The call to getConstructor() without parameters requires the class to have a default constructor. The following test illustrates this.

好像您的类提供了一个不是默认构造函数的构造函数。不带参数调用 getConstructor() 要求类具有默认构造函数。下面的测试说明了这一点。

import org.junit.Test;

public class ConstructorTest {
    public static class ClassWithParameterizedConstructor {
        public ClassWithParameterizedConstructor(final String param) {
            // A parameterized constructor, no default constructor exists
        }
    }

    @Test
    public void testFoo() throws NoSuchMethodException {
        // Parameterized constructor lookup works fine
        ClassWithParameterizedConstructor.class.getConstructor(String.class);

        // This doesn't work since there is no default constructor
        ClassWithParameterizedConstructor.class.getConstructor();
    }
}

So, a possible solution is to either change the call to getConstructor() to include the correct type or to provide a default constructor on the object itself (but why would you do that?).

因此,一个可能的解决方案是更改对 getConstructor() 的调用以包含正确的类型或在对象本身上提供默认构造函数(但为什么要这样做?)。

回答by Luis Alves

Read this: http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

阅读:http: //docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

It seems that both classes Class and Constructor have the method newInstance the difference is that in the Class class you can only call newInstance with no arguments, so the called constructor must have an no arguments (this also brings a problem when you have more that one constructor). The methoe newInstance in the Constructor class allows you to call the constructor with arguments also, notice that you can also use the method getConstructors instead of getConstructor that returns you all the class constructors and allows you to call the constructor method you want.

似乎 Class 和 Constructor 类都有 newInstance 方法,区别在于在 Class 类中你只能不带参数调用 newInstance,所以被调用的构造器必须不带参数(这也会带来一个问题,当你有更多的时候构造函数)。Constructor 类中的methoe newInstance 也允许您使用参数调用构造函数,请注意,您还可以使用方法 getConstructors 而不是 getConstructor ,它返回所有类构造函数并允许您调用所需的构造函数方法。

In this case, since you only have one constructor only and with no arguments, Class.newInstance works fine. To use the getConstructor to have the same result you'll need to add in the end oCon.newInstance();

在这种情况下,由于您只有一个构造函数并且没有参数,因此 Class.newInstance 可以正常工作。要使用 getConstructor 获得相同的结果,您需要在末尾添加 oCon.newInstance();

回答by Arthur Kupriyanov

You can use getDeclaredConstructors()which returns an array of Constructor objects reflecting all the constructors declared by the class represented by this Class object

您可以使用getDeclaredConstructors()which 返回一个 Constructor 对象数组,反映由该 Class 对象表示的类声明的所有构造函数

class SomeClass{

    {
        System.out.println("I'am here!");
    }

}

public class Main {
    public static void main(String[] args) throws Exception{

        System.out.println(Arrays.toString(SomeClass.class.getDeclaredConstructors()));
        // returns public, protected, default (package) access, and private constructors

        // System.out.println(SomeClass.class.getConstructor());
        // in that case you got:
        // NoSuchMethodException: reflection.SomeClass.<init>()
        // because SomeClass don't have public constructor

        for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){

            constructor.newInstance();
        }

    }
}

And if you have private constructor like this:

如果你有这样的私有构造函数:

class SomeClass{

    private SomeClass(String val){
        System.out.println(val);
    }

}

You have to set accessible for constructor:

您必须为构造函数设置可访问:

constructor.setAccessible(true);

And get something like this:

得到这样的东西:

class SomeClass{

    private SomeClass(String val){
        System.out.println(val);
    }

}

public class Main {
    public static void main(String[] args) throws Exception{

        for (Constructor constructor : SomeClass.class.getDeclaredConstructors()){
            // constructor.newInstance("some arg");    // java.lang.IllegalAccessException
            constructor.setAccessible(true);
            constructor.newInstance("some arg");
        }

    }
}

Note: if your class declared as privatehis default constructor must be privatetoo.

注意:如果您的类声明为private他的默认构造函数,则必须也是private如此。

And be careful with nonstatic-inner classes, which receives an outer class instance

并注意接收外部类实例的非静态内部类

回答by sxc731

In this (somewhat convoluted) scenario, it's actually possible to get hold of the (non-public) constructor by replacing:

在这种(有点复杂)的情况下,实际上可以通过替换来获取(非公共)构造函数:

Constructor<?> oCon = o.getConstructor();

with

Constructor<?> oCon = o.getDeclaredConstructor();

The "default" visibility of the Jedenclass (and its constructor) makes it accessible to the Startclass, since it's defined in the same package.

Jeden类(及其构造函数)的“默认”可见性使其可以被Start类访问,因为它是在同一个包中定义的。