getConstructorはJavaでNoSuchMethodExceptionをスローします

Oct 15 2020

私はJavaに非常に慣れていないので、これはばかげた質問かもしれませんが、既存のインスタンスからクラスを取得してクラスの新しいインスタンスを作成する方法を理解しようとしています(これはリフレクションと呼ばれると思います)。

現在、私はスーパークラスとそのいくつかのサブクラスを持っています。

public abstract class SuperClazz {...}

public class SubClazz1 extends SuperClazz {...}

public class SubClazz2 extends SuperClazz {...}

これらのサブクラスの1つの既存のインスタンスがあります(どのサブクラスに属するかまだわからないため、スーパークラスのメンバーとしてのみ宣言されています)。この既存のインスタンスが属するサブクラスを取得して、同じサブクラスの新しいインスタンスを作成しようとしています。

これは私の設定です:

private SuperClazz oldSubInstance;
private SuperClazz newSubInstance;

newSubInstance = oldSubInstance.getClass().getConstructor(String.class, char.class, int.class).newInstance("abc", 'e', 6);

NoSuchMethodExceptionをスローします。

SuperClazzには、String、char、intの3つのパラメーターを受け取るコンストラクターがあることを知っているので混乱しています。私はこことここで答えを見ましたが、提案された修正の実装が機能しないか、それらの問題が私の状況に当てはまらないことがわかりました。

getConstructorがどのように機能するかを完全に誤解していますか?

回答

AlexRudenko Oct 15 2020 at 20:04

all-argsコンストラクターが子クラスに存在することを確認する必要があります。

次の例では、newSubInstance:を作成します。

// using Lombok annotations for brevity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
abstract class SuperClazz {
    private String str;
    private char chr;
    private int x;

    // getters/setters/default and all-args constructors provided by Lombok
}


class SubClazz1 extends SuperClazz {
    public SubClazz1(String str, char c, int i) { // providing constructor in the child class
        super(str, c, i);
    }
}

// test
SuperClazz oldSubInstance = new SubClazz1("def", 'g', 10);
SuperClazz newSubInstance;

newSubInstance = oldSubInstance.getClass()
                               .getConstructor(String.class, char.class, int.class)
                               .newInstance("abc", 'e', 6);

System.out.println(newSubInstance);

出力(toString基本クラスレベルでオーバーライド):

SuperClazz(str=abc, chr=e, x=6)