15

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"されます。

4

5 に答える 5

27

次のjavadoc.getConstructor()を読むと、問題は明らかです。

この Class オブジェクトによって表されるクラスの指定されたパブリックコンストラクターを反映する Constructor オブジェクトを返します。

鉱山を強調します。

あなたのコードでは、コンストラクターはパブリックではありません!

例:

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

JLS参照も提供するSO回答への必須のリンク。特に、既定のコンストラクターには、クラスと同じアクセス修飾子があることに注意してください。

于 2014-12-20T12:01:33.423 に答える
2

クラスがデフォルトのコンストラクターではないコンストラクターを提供しているようです。パラメーターなしで 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() への呼び出しを変更して正しい型を含めるか、オブジェクト自体にデフォルトのコンストラクターを提供することです (しかし、なぜそれを行うのでしょうか?)。

于 2014-12-20T12:00:22.087 に答える
1

これを読んでください:http://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

Class と Constructor の両方のクラスにメソッド newInstance があるようです。違いは、Class クラスでは newInstance を引数なしでしか呼び出せないため、呼び出されたコンストラクターには引数が必要ないことです (これは、複数の引数がある場合にも問題を引き起こします)コンストラクタ)。Constructor クラスのメソッド newInstance を使用すると、引数を指定してコンストラクターを呼び出すこともできます。すべてのクラス コンストラクターを返し、必要なコンストラクター メソッドを呼び出すことができる getConstructor の代わりに getConstructors メソッドを使用できることに注意してください。

この場合、コンストラクターは 1 つしかなく、引数がないため、Class.newInstance は正常に機能します。getConstructor を使用して同じ結果を得るには、最後に oCon.newInstance(); を追加する必要があります。

于 2014-12-20T12:05:18.910 に答える