getConstructor Java'da NoSuchMethodException Atıyor

Oct 15 2020

Java'da çok yeniyim, bu yüzden bu aptalca bir soru olabilir, ancak sınıfı mevcut bir örnekten alarak bir sınıfın yeni bir örneğini nasıl yaratacağımı anlamaya çalışıyorum (buna yansıma denir).

Şu anda bir süper sınıfım ve birkaç alt sınıfım var.

public abstract class SuperClazz {...}

public class SubClazz1 extends SuperClazz {...}

public class SubClazz2 extends SuperClazz {...}

Bu alt sınıflardan birinin mevcut bir örneğine sahibim (henüz hangi alt sınıfa ait olacağını bilmediğim için yalnızca süper sınıfın bir üyesi olarak ilan edildi). Bu mevcut örneğin hangi alt sınıfa ait olduğunu almaya ve aynı alt sınıfın yeni bir örneğini oluşturmaya çalışıyorum.

Bu benim kurulumum:

private SuperClazz oldSubInstance;
private SuperClazz newSubInstance;

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

Hangi NoSuchMethodException atar.

Kafam karıştı çünkü SuperClazz'ın üç parametre, bir String, bir char ve bir int alan bir kurucuya sahip olduğunu biliyorum. Cevapları burada ve burada inceledim, ancak önerilen düzeltmeleri uygulamanın işe yaramadığını veya sorunlarının benim durumum için geçerli olmadığını gördüm.

GetConstructor'ın nasıl çalıştığını tamamen yanlış mı anlıyorum?

Yanıtlar

AlexRudenko Oct 15 2020 at 20:04

All-args yapıcısının alt sınıf (lar) da var olduğundan emin olmanız gerekir.

Aşağıdaki örnek bir 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);

çıktı ( toStringtemel sınıf düzeyinde geçersiz kılınır):

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