[英]getConstructor with no parameters
我似乎无法将getConstructor
用于没有参数的构造函数。
我不断收到以下异常:
java.lang.NoSuchMethodException: classname.<init>()
这是代码:
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();
打印"konstruktor"
没有问题。
当您阅读.getConstructor()
的javadoc 时,问题.getConstructor()
清楚了:
返回一个 Constructor 对象,该对象反映了此 Class 对象表示的类的指定公共构造函数。
强调我的。
在您的代码中,构造函数不是公开的!
例子:
// 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();
}
}
好像您的类提供了一个不是默认构造函数的构造函数。 不带参数调用 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() 的调用以包含正确的类型或在对象本身上提供默认构造函数(但为什么要这样做?)。
阅读: 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();
您可以使用getDeclaredConstructors()
返回一个 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();
}
}
}
如果你有这样的私有构造函数:
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
。
并注意接收外部类实例的非静态内部类
在这种(有点复杂)的情况下,实际上可以通过替换来获取(非公共)构造函数:
Constructor<?> oCon = o.getConstructor();
和
Constructor<?> oCon = o.getDeclaredConstructor();
Jeden
类(及其构造函数)的“默认”可见性使其可被Start
类访问,因为它是在同一个包中定义的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.