Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java reflection get constructor from class name failed [closed]

I've this code snippet:

class You{
    public You(String s){}
}

public static void main(String[] args)  throws NoSuchMethodException {
    Constructor[] constructors = You.class.getConstructors();
    for(Constructor constructor: constructors){
        Class[] parameterTypes = constructor.getParameterTypes();
        for(Class c: parameterTypes){
            System.out.println(c.getName());//print java.lang.String
        }
    }
    Constructor constructor =
            You.class.getConstructor(String.class);//NoSuchMethodException?
}

This is quite old, when I print the constructors, it has one constructor with java.lang.String as parameter. But when I tried to You.class.getConstructor it says no constructor with String.class as parameter.

I'm using java1.8 on mac. Would you help to explain and how to fix?

Thanks a lot.

like image 875
Troskyvs Avatar asked Aug 05 '26 14:08

Troskyvs


2 Answers

I'll delete this answer if it's not the case, but it looks like You is an inner class, and I suspect your actual code looks something like this:

public class Foo {

    class You {
        public You(String s){}
    }

    public static void main(String[] args)  throws NoSuchMethodException {
        Constructor[] constructors = You.class.getConstructors();

        for (Constructor constructor: constructors) {
            Class[] parameterTypes = constructor.getParameterTypes();

            for (Class c: parameterTypes){
                System.out.println(c.getName());//print java.lang.String
            }
        }

        Constructor constructor =
            You.class.getConstructor(String.class);//NoSuchMethodException?
    }
}

From the documentation of Class#getConstructor:

If this Class object represents an inner class declared in a non-static context, the formal parameter types include the explicit enclosing instance as the first parameter.

For this reason, you'll have to use the following instead:

Constructor constructor = You.class.getConstructor(Foo.class, String.class);

But obviously replace Foo with the name of your enclosing class.

like image 112
Jacob G. Avatar answered Aug 07 '26 04:08

Jacob G.


If You is really an inner class then you need to get its constructor a little bit differently.

Here is the Javadoc snippet from Class.getConstructor

If this Class object represents an inner class declared in a non-static context, the formal parameter types include the explicit enclosing instance as the first parameter.

This means that you need to also pass enclosing class to the Class.getConstructor call.

Here is an example (includes how to create an instance of inner class from its Constructor):

public class Test {
    class You{
        public You(String s){}
    }

    public static void main(String[] args)  throws NoSuchMethodException {
        Constructor constructor =
                You.class.getConstructor(Test.class, String.class);//NoSuchMethodException?

        try {
            You you = constructor.newInstance(new Test(), "");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
like image 37
tsolakp Avatar answered Aug 07 '26 02:08

tsolakp