getConstructor()在java中没有参数

时间:2014-12-20 11:33:09

标签: java getconstructor

我似乎无法将getConstructor()用于没有参数的构造函数。 我一直在

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

这是代码

import java.lang.reflect.*;
class asa implements InfoInterface{

public String getClassName()
{
    return("jeden");
}
public String getMethodName()
{
    return("metoda");
}
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 ) {
    String klasa, metoda, argument;
    InfoInterface d;
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] );
    d=(InfoInterface)c.newInstance();
    klasa = d.getClassName();
    metoda = d.getMethodName();
    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();打印&#34; konstruktor&#34;没有问题

5 个答案:

答案 0 :(得分:20)

当您阅读javadoc of .getConstructor()

时,问题就很明显了
  

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

强调我的。

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

示例:

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

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

答案 1 :(得分:2)

好像你的类提供了一个 NOT 默认构造函数的构造函数。对没有参数的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();
    }
}

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

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:0)

您可以使用getDeclaredConstructors()返回一个构造函数对象数组,该数组反映由该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();
        }

    }
}

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

class SomeClass{

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

}

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

constructor.setAccessible(true);

得到这样的东西:

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

    }
}

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

请注意非静态内部类,该类会接收外部类实例

答案 4 :(得分:0)

在这种(有些令人费解的)场景中,实际上可以通过替换来获得(非公共)构造函数:

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

使用

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

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