Tenho algumas classes que funcionam basicamente como modelo (POJO), mas além do construtor principal nestas classes, incluí uma sobrecarga do construtor para que ele receba um JSONObject e preencha os atributos da classe. Estas classes implementam uma interface que é informada na classe genérica, para que só classes que implementem esta interface sejam permitidas.
Além destas classes, criei uma classe genérica que irá servir como um cliente para o acesso a WebServices (REST) e com a resposta da requisição, consiga retornar um objeto da classe informada na instanciação da classe genérica, através de uma função getContentAsObject().
Porém não consigo instanciar a classe modelo definida na classe genérica e passar o conteúdo JSONObject que será transformado em modelo.
Como consigo fazer isto?
Olá,
Não sei se entendi muito bem sua pergunta. Você precisa instanciar uma classe concreta que tem como superclasse uma classe com dois construtores?
Se for isso, você deve fazer uma chamada ao construtor da classe pai, algo mais ou menos desta forma:
class MinhaClasse extends MinhaSuperClasse {
MinhaClasse(JSONObject obj) {
super(obj); // Chama o construtor sobrecarregado da superclasse
}
}
[ ]'s
Na verdade o que eu preciso é diferente.
Tenho várias classes que implementam a interface IViewModel, além disso tenho uma classe genérica RestClient que aceita classes que implementem esta interface.
public class RestClient<T extends IViewModel>
{
public T getResponseAsObject() {
// ...
}
}
Preciso que ao executar a função getResponseAsObject, seja instanciada uma classe do tipo T e para isto seja passado um parâmetro, ficando algo do tipo:
public T getResponseAsObject() {
T obj = new T(parametro);
}
Em java isso não é possível.
Não é possível chamar o construtor de T.
Normalmente, para se chamar o construtor de T, deve-se passar T.class no construtor da classe genérica. Um exemplo (não sei se compila, provavelmente você terá de tratar alguma exceção) :
class Abc<T> {
public Abc(Class<T> tKlass) {
this.tKlass = tKlass;
}
public T getResponseAsObject () {
T t = tKlass.newInstance();
return t;
}
private Class<T> tKlass;
}
Mas neste caso a classe do tipo T não consegue receber parâmetros no seu construtor através do newInstance, certo?
Algo tipo:
T t = tKlass.newInstance(“MeuParametroString”);
Uh, isso é um pouco mais complicado. Você sabe se essa classe tem apenas esse construtor (que recebe apenas uma string, e nada mais)? Se for isso, então podemos fazer algo como (obviamente você tem de pôr o tratamento de exceções
) :
public T getResponseAsObject () {
Constructor<T> tConstr = tKlass.getConstructor (String.class);
T t = tConstr.newInstance ("MeuParametroString");
return t;
}
Sim, sempre terá apenas um parâmetro. Na verdade é do tipo JSONObject, mas será apenas este sempre.
Vou testar no meu código.
Valeu!
Dica: getConstructor é uma operação que leva algum tempo (porque ele precisa procurar, na lista de construtores de uma determinada classe, qual é o construtor correto).
Você pode fazer uma otimização como esta aqui:
class Abc<T> {
public Abc(Class<T> tKlass) {
this.tKlass = tKlass;
this.tConstructor = tKlass.getConstructor (JSONObject.class);
}
public T getResponseAsObject () {
T t = tConstructor.newInstance (theResponseAsJSONObject);
return t;
}
private Class<T> tKlass;
private Constructor<T> tConstructor;
}
Neste caso posso considerar a passagem do parâmetro através de um método e não do construtor, assim não precisaria de métodos de reflection.
Obs: a aplicação é para Android.