getConstructor lança NoSuchMethodException em Java
Sou muito novo em Java, então essa pode ser uma pergunta idiota, mas estou tentando entender como criar uma nova instância de uma classe obtendo a classe de uma instância existente (acho que isso se chama reflexão).
Atualmente tenho uma superclasse e várias subclasses dela.
public abstract class SuperClazz {...}
public class SubClazz1 extends SuperClazz {...}
public class SubClazz2 extends SuperClazz {...}
Eu tenho uma instância existente de uma dessas subclasses (declarada apenas como membro da superclasse, pois ainda não sei a qual subclasse ela pertencerá). Estou tentando obter qualquer subclasse a que pertence esta instância existente e fazer uma nova instância dessa mesma subclasse.
Esta é a minha configuração:
private SuperClazz oldSubInstance;
private SuperClazz newSubInstance;
newSubInstance = oldSubInstance.getClass().getConstructor(String.class, char.class, int.class).newInstance("abc", 'e', 6);
Que lança NoSuchMethodException.
Estou confuso porque sei que o SuperClazz tem um construtor que leva em três parâmetros, um String, um char e um int. Eu vi as respostas aqui e aqui, mas descobri que implementar as correções sugeridas não funciona ou que seus problemas não se aplicam à minha situação.
Estou totalmente mal entendido como getConstructor funciona?
Respostas
Você precisa ter certeza de que o construtor all-args existe na (s) classe (s) filha.
O exemplo a seguir cria um 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);
saída ( toStringsubstituído no nível da classe base):
SuperClazz(str=abc, chr=e, x=6)