Casting com Objetos

27 respostas
J

e o Seguinte tenho estes objetos

Objeto-1

public interface Status {
	public Integer getStatus();
	public void setStatus(Integer status);
}

Objeto-2

public class StatusFinDocumento extends FinDocumento implements Status {
	private Integer status;
	
	@Override
	public Integer getStatus() {
		// TODO Auto-generated method stub
		return status;
	}	
	@Override
	public void setStatus(Integer status) {
		// TODO Auto-generated method stub
		this.status = status;
	}
}

Objeto-3

public class CarrinhoSaidaWrapper<T extends Status> {
	private List<T> lista = new ArrayList<T>();
	private Double total;
	private Integer quantidade;
	
	public List<T> getLista() {
		return lista;
	}
	public void setLista(List<T> lista) {
		this.lista = lista;
	}
}

Objeto-4

public class Manutencao {

	/**
	 * @param args
	 * @throws ParseException 
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CarrinhoSaidaWrapper<StatusFinDocumento> lista = new CarrinhoSaidaWrapper<StatusFinDocumento>();
		FinDocumento finDocumento = new FinDocumento();
		finDocumento.setDesdobramento("X");
		lista.getLista().add((StatusFinDocumento) finDocumento);
	}

}

Quando Executo o Objeto Manutencao da exception alguem poderia me ajudar

Exception in thread "main" java.lang.ClassCastException: br.inf.xxx.modelo.FinDocumento cannot be cast to br.inf.xxx.modelo.StatusFinDocumento
	at br.inf.xxx.xxx.test.Manutencao.main(Manutencao.java:24)

Obrigado !!!
JVDS

27 Respostas

Eric_Yuzo

O cast converte a referência que originalmente é de FinDocumento para StatusFinDocumento. Mas o objeto FinDocumento não pode ser convertido para um objeto StatusFinDocumento. Por isso ocorre a exceção em tempo de execução.

J

Tem alguma outra forma de eu resolver isso.

G

Isso resolve?

CarrinhoSaidaWrapper<? extends StatusFinDocumento> lista = new CarrinhoSaidaWrapper<? extends StatusFinDocumento>();

E dá para remover o cast no método add.

Eric_Yuzo

Para que o cast para StatusFinDocumento dê certo é preciso que o objeto seja originalmente do tipo StatusFinDocumento.

CarrinhoSaidaWrapper<StatusFinDocumento> lista = new CarrinhoSaidaWrapper<StatusFinDocumento>(); FinDocumento finDocumento = new StatusFinDocumento(); // Apesar da referência ser do tipo FinDocumento, o objeto é do tipo StatusFinDocumento, assim o cast pode ser feito sem gerar exceção. finDocumento.setDesdobramento("X"); lista.getLista().add((StatusFinDocumento) finDocumento);

J

garcia-jj:
Isso resolve?

CarrinhoSaidaWrapper<? extends StatusFinDocumento> lista = new CarrinhoSaidaWrapper<? extends StatusFinDocumento>();

E dá para remover o cast no método add.

Nao deu certo o q posso fazer.

Obrigado!!!
JVDS

G

Dizer que não deu certo é muito vago, e assim fica muito dificil de te ajudar.

Antes de mais nada veja qual a mensagem de erro, entenda-a e faça as alterações no código. Além disso lembre-se que se você tem uma coleção tipada, você só consegue colocar lá dentro objetos do mesmo tipo, ou no caso dos wildcards, você consegue colocar filhos.

J

garcia-jj:
Dizer que não deu certo é muito vago, e assim fica muito dificil de te ajudar.

Antes de mais nada veja qual a mensagem de erro, entenda-a e faça as alterações no código. Além disso lembre-se que se você tem uma coleção tipada, você só consegue colocar lá dentro objetos do mesmo tipo, ou no caso dos wildcards, você consegue colocar filhos.

Desculpe por nao mostrar o erro este codigo que vc me falou ja no eclipse da erro de cara de sintaxe agora vc me pegou por exemplo esta tabela nao tem filhos acho que nao vou precisar disso codigo(Eric Yuzo) aqui funcionou.

CarrinhoSaidaWrapper<StatusFinDocumento> lista = new CarrinhoSaidaWrapper<StatusFinDocumento>();
		FinDocumento finDocumento = new StatusFinDocumento(); // Apesar da referência ser do tipo FinDocumento, o objeto é do tipo StatusFinDocumento, assim o cast pode ser feito sem gerar exceção.
		finDocumento.setDesdobramento("X");
		lista.getLista().add((StatusFinDocumento) finDocumento);

Caso vc tiver alguma outra ideia posta ai valeu pela atenção.

J

Quero saber agora como faço para pegar uma lista ja existente e tranformar ela em List.

CarrinhoSaidaWrapper<StatusFinDocumento> lista = new CarrinhoSaidaWrapper<StatusFinDocumento>();
List<T> listafindocumento;
lista.setLista((List<StatusFinDocumento>)listafindocumento);//Erro de sintaxe

Obrigado !!!
JVDS

G

lista.addAll?

J

lista.addAll?

Eu quiz dizer assim lista.SetLista().

Sabendo que este lista ele e meu objeto carrinho que trabalha com generics.

G

Se você criar o método setLista será possível :slight_smile:

J

Sim entao ja tenho so que nao compila se vc olhar no primeiro post dos codigo Chama CarrinhoSaidaWrapper.

So que nao compila ja da erro de sintaxe se eu for fazer cast

Ok.

Lucas_Cavalcanti

não tá compilando pq vc não inicializou a lista…

tenta fazer:

CarrinhoSaidaWrapper<StatusFinDocumento> lista = new CarrinhoSaidaWrapper<StatusFinDocumento>();  
List<T> listafindocumento = null; //!!!!! 
lista.setLista((List<StatusFinDocumento>)listafindocumento);
J

Lucas Cavalcanti:
não tá compilando pq vc não inicializou a lista…

tenta fazer:

CarrinhoSaidaWrapper<StatusFinDocumento> lista = new CarrinhoSaidaWrapper<StatusFinDocumento>(); List<T> listafindocumento = null; //!!!!! lista.setLista((List<StatusFinDocumento>)listafindocumento);

Lucas, vou tentar te explicar o que esta acontecendo tenho meu DaoHibernate que tem o seguinte metodo

DaoHibernate.java

public List<T> lista(Class clazz, Object camposPrk) {
		// TODO Auto-generated method stub
		return selectHql.list();
	}

FinDocumentoController.java

public class FinDocumentoController extends GenericoController<FinDocumento> {
	@Get
	public void find(Integer id) throws ParseException {
		// TODO Auto-generated method stub	
		this.carrinhosaida.setLista(super.lista(id));
		this.result.use(Results.logic()).redirectTo(getClass()).formulario();		
	}
}

CarrinhoSaidaWrapper.java

public class CarrinhoSaidaWrapper<T extends Status> {
	private List<? extends Status> lista = new ArrayList<T>();
	private Double total;
	private Integer quantidade;

	public List<T> getLista() {
		return (List<T>) lista;
	}
	
	public void setLista(List<?> list) {
		this.lista = (List<? extends Status>)list;
	}
}

O que esta acontecendo e o seguinte recebo a lista do hibernate e passo para o CarrinhoSaida via setter ok, ou seja estou recebendo uma lista do tipo FinDocumento so que quando eu acesso esta lista no meu jsp ele fala que nao existe o campo status mas se no metodo setter de meu carrinho eu fiz (List<? extends Status>)list num deveria ir o campo status.

Lucas_Cavalcanti

o nome do campo é lista, mesmo que seja uma List<? extends Status> (por causa do getLista())

J

lucas nao entedi o que vc explicou no JSP meu estou acessando desta forma

${carrinhosaida.lista[0].nome_campo} => ${carrinhosaida.lista[0].id} = FUNCIONA
${carrinhosaida.lista[0].nome_campo} => ${carrinhosaida.lista[0].status} = ERRO

Obrigado !!!
JVDS

Lucas_Cavalcanti

existe o método getStatus na classe status?

J

sim tanto getter como setter

Lucas_Cavalcanti

tenta colocar no jsp, em algum lugar visível:

${carrinhosaida.lista[0].class}

o que aparece? essa classe é um Status?

J

Lucas Cavalcanti:
tenta colocar no jsp, em algum lugar visível:

${carrinhosaida.lista[0].class}

o que aparece? essa classe é um Status?

Nao esta br.com.modelo.FinDocumento e isso que nao entendo lembrando que eu fiz no CarrinhoSaida no setter lista

public void setLista(List<?> list) {
		this.lista = (List<? extends Status>)list;  //Isso aqui nao deveria extender o que ta vindo FinDocumento extends Status
	}

Obrigado !!!
JVDS

Lucas_Cavalcanti

não entendi o que vc falou… qual é o problema?

J

Vou tentar explicar melhor quando eu passo para meu

CarrinhoSaidaWrapper

carrinhosaida.setLista(super.lista());

Deveira a lista herdar o campo status.

Pelo que vi nao esta herdando foi que falei no JSP neste topico http://www.guj.com.br/posts/list/15/227753.java#1168947

Obrigado !!!
JVDS

Eric_Yuzo

Dá erro porque FinDocumento não implementa a interface Status.

[email removido:
] public void setLista(List<?> list) { this.lista = (List<? extends Status>)list; //Isso aqui nao deveria extender o que ta vindo FinDocumento extends Status }

Não, a declaração List<? extends Status> não deveria extender o que ta vindo. “? extends Status” diz que a lista em questão só deve aceitar que objetos do tipo Status sejam adicionados, ou seja, aqueles que implementem a interface Status, que não é o caso de FinDocumento.

J

Eric Yuzo:
Dá erro porque FinDocumento não implementa a interface Status.

[email removido:
] public void setLista(List<?> list) { this.lista = (List<? extends Status>)list; //Isso aqui nao deveria extender o que ta vindo FinDocumento extends Status }

Não, a declaração List<? extends Status> não deveria extender o que ta vindo. “? extends Status” diz que a lista em questão só deve aceitar que objetos do tipo Status sejam adicionados, ou seja, aqueles que implementem a interface Status, que não é o caso de FinDocumento.

Tem alguma forma de resolver isso ?

Obrigado !!!
JVDS

Eric_Yuzo

Como assim, resolver?

FinDocumento não possui o atributo status, por isso dá erro quando tenta acessá-lo.

A classe que possui o status é StatusFinDocumento do primeiro post. Portanto são objetos desta classe que devem ser adicionados a lista.

J

Eric Yuzo:
Como assim, resolver?

FinDocumento não possui o atributo status, por isso dá erro quando tenta acessá-lo.

A classe que possui o status é StatusFinDocumento do primeiro post. Portanto são objetos desta classe que devem ser adicionados a lista.

Então quando faço FinDocumento extends Status no metodo setLista ele nao gera um outro objeto com herança e sim FinDocumento.

Ok então vou ver sem tem outra forma de eu resolver este poblema.

Obrigado !!!
JVDS

Eric_Yuzo
[email removido:
]Então quando faço FinDocumento extends Status no metodo setLista ele nao gera um outro objeto com herança e sim FinDocumento.
Mas a declaração do método setLista não serve mesmo para gerar um outro objeto.
List<? extends Status>
Generics é usado para parametrizar a classe List. Fazendo uma analogia bem tosca é como se fosse uma etiqueta, se colar uma etiqueta escrito vinho em um barril e colocar água dentro dele, não vai sair vinho só por que na etiqueta está escrito vinho, saírá o que foi colocado dentro dele, no caso a água. Porém, no caso da lista com generics, se tentar adicionar um objeto que não seja do tipo especificado, gera um erro de compilação. Quanto ao casting, ele converte a referência e não o objeto. Exemplo:
List lista; // Declarei uma variável lista com o tipo List para não limitar os tipos de lista que podem ser referenciados.

lista = new ArrayList(); // Passei a referência de um ArrayList, que é uma classe concreta que implementa a interface List.

ArrayList arrayList = (ArrayList) lista; // Declarei uma variável do tipo ArrayList e passei a referência do objeto que foi criado acima a partir de lista, como lista é do tipo List, precisei fazer o cast para ArrayList. Mas na verdade o objeto ArrayList que foi criado não sofreu modificações, o que mudou foi a referência, que agora pode acessar métodos que estão declarados em ArrayList e não em List.

LinkedList linkedList = (LinkedList) lista; // Declarei uma variável do tipo LinkedList e tentei passar a referência do objeto em lista fazendo o cast para LinkedList. Como LinkedList implementa a interface List, a tentativa de fazer o cast não gera erro de compilação, porém vai gerar um ClassCastException, pois o objeto instanciado na memória não é um LinkedList e sim um ArrayList.
Então, seu objeto FinDocumento não vai se transformar milagrosamente em um objeto StatusFinDocumento. É preciso que você gere os objetos Status e passe para sua lista.
Criado 16 de dezembro de 2010
Ultima resposta 22 de dez. de 2010
Respostas 27
Participantes 4