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
getConstructor with no parameters
提问by user3086720
I can't seem to use getConstructor
for 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.
回答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 private
his default constructor must be private
too.
注意:如果您的类声明为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 Jeden
class (and its constructor) makes it accessible to the Start
class, since it's defined in the same package.
Jeden
类(及其构造函数)的“默认”可见性使其可以被Start
类访问,因为它是在同一个包中定义的。