getConstructor выдает исключение NoSuchMethodException в Java

Oct 15 2020

Я очень новичок в Java, поэтому это может быть глупый вопрос, но я пытаюсь понять, как создать новый экземпляр класса, получив класс из существующего экземпляра (я думаю, что это называется отражением).

В настоящее время у меня есть суперкласс и несколько его подклассов.

public abstract class SuperClazz {...}

public class SubClazz1 extends SuperClazz {...}

public class SubClazz2 extends SuperClazz {...}

У меня есть существующий экземпляр одного из этих подклассов (объявлен только как член суперкласса, поскольку я еще не знаю, к какому подклассу он будет принадлежать). Я пытаюсь получить тот подкласс, к которому принадлежит существующий экземпляр, и создать новый экземпляр того же подкласса.

Это моя установка:

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. Я просмотрел ответы здесь и здесь, но обнаружил, что реализация предложенных исправлений не работает или их проблемы не относятся к моей ситуации.

Я совершенно не понимаю, как работает 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)