简体   繁体   中英

JAVA getConstructor throws NoSuchMethodException

I'm new in JAVA and I'm trying to learn reflection . I want to get specific constructor (picking the example form here ) from my class :

public class Example1 {
    public Example1() {
    }

    public Example1(int i) {
    }

    public Example1(String s) {
        System.out.println("using param = " + s);
    }

    public static void main(String[] args) throws Exception {  
        Class<?>[] paramTypes = String.class.getClasses();
        Constructor<Example1> ctor = Example1.class.getConstructor(paramTypes);
        ctor.newInstance("test");
    }
}

I get NoSuchMethodException when trying to instantiate ctor

What am I missing here?

Working example:

import java.lang.reflect.Constructor;

public class Test {
    public Test(String str) {
        System.out.println(str);
    }

    public Test(int a, int b) {
        System.out.println("Sum is " + (a + b));
    }

    public static void main(String[] args) throws Exception {
        Constructor<Test> constructorStr = Test.class.getConstructor(String.class);
        constructorStr.newInstance("Hello, world!");

        Constructor<Test> constructorInts = Test.class.getConstructor(int.class, int.class);
        constructorInts.newInstance(2, 3);
    }
}

Note that method getConstructor actually doesn't take an array. It's defined like:

public Constructor<T> getConstructor(Class<?>... parameterTypes) {

... meaning that it accepts variable amount of arguments which should have been passed as I did. Passing an array is possible too, but it's not necessary.

What you've done originally was equivalent to:

    Constructor<Test> constructor = Test.class.getConstructor(String.class.getClasses());
    constructor.newInstance("Hello");

But, what does String.class.getClasses() return? Good question! Lets go debug:

    Class<?>[] classes = String.class.getClasses();
    System.out.println(classes.length); // prints 0

There's a documentation about getClasses() : https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getClasses . Check it and you'll find out the reason why it's so.

For the sake of completeness. The super-original-question (before edits) contained one more constructor - a non-parametric one:

import java.lang.reflect.Constructor;

public class Example1 {
    public Example1() {
    }

    public Example1(String s) {
        System.out.println("using param = " + s);
    }

    public static void main(String[] args) throws Exception {  
        Constructor<Example1> ctor = Example1.class.getConstructor(String.class.getClasses());
        ctor.newInstance("test");
    }
}

The problem which occurs here is IllegalArgumentException being thrown. It's because even though String.class.getClasses() returns an empty array, there actually is constructor which matches the criteria - a non-parametric constructor! It doesn't have any arguments and the array returned by String.class.getClasses() doesn't contain anything too. This means that constructor is successfully found, but when trying to instantiate it using ctor.newInstance("test") , it fails because the found constructor doesn't accept any arguments.

Try it using

Constructor<example1> ctor = examTesting.getConstructor(new Class[]{String.class});

This will return the constructor with one parameter of type String. Your method might return multiple values and therefore a constructor with multiple parameter is searched but not found -> NoSuchMethodException is thrown.

More information about getClasses(): http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getClasses%28%29

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM