Problema com classe genérica

6 respostas
Orlando.Neto

Bom dia pessoal, estou tendo um problema com o generic e gostaria de compartilhar com vocês.
a estrutura é a seguinte:

Tenho a seguinte classe pai, sendo que ela contem um lista de SerialModel

public abstract class MovimentacaoItem<T extends Produto> extends AbstractModel implements ItemMovimentacao {
//...
private Set<SerialModel> seriaisSugeridos;
//...
}

Essa classe tem duas classes filhas que são as seguintes:

public abstract class MaterialMovimentacao extends MovimentacaoItem<Material> {
//....
}
public abstract class ComponenteMovimentacao extends MovimentacaoItem<Montagem> {
//...
}

Essa é a estrutura.

Na classe controller eu tenho o seguinte método:

private void extractSerial(List<? extends MovimentacaoItem> items, ModelAndView modelAndView, String type) {
		Integer lastIndex = 0;
		for (MovimentacaoItem item : items) {
			if (item.isSerialized()) {
				for (SerialModel serial : item.getSeriaisSugeridos()) { // <---- Problema aqui
					lastIndex += 1;
					String index = type + lastIndex;
					modelAndView.addObject(index, serial);
				}
//....

Porém o " item.getSeriaisSugeridos()" não vem tipado, sendo então o Set interpretado como sendo de Object e não de SerialModel.
Se eu tiro o generic da classe MovimentacaoItem o método getSeriaisSugeridos vem tipado normalmente Set, porém se minha classe MovimentacaoItem for generic o método getSeriaisSugeridos retorna apenas um Set.

Alguma poderia me explicar o porque isso ocorre?

desde já obrigado a todos.

6 Respostas

cpsilva

Olha o meu comentário pode ser jr mas vou fazer heheh…
Não dá para vc sobreescrever o metodo?

R

private void extractSerial(List<? extends MovimentacaoItem> items, ModelAndView modelAndView, String type) { Integer lastIndex = 0; for (MovimentacaoItem item : items) { if (item.isSerialized()) { for (SerialModel serial : item.getSeriaisSugeridos()) { // <---- Problema aqui lastIndex += 1; String index = type + lastIndex; modelAndView.addObject(index, serial); } //....

Se sempre itens vai herdar MovimentacaoItem que implementa ItemMovimentacao. Por quê a Lista não é o tipo da interface ItemMovimentacao?
Dai basta colocar a assinatura do método getSeriaisSugeridos() na interface.

MovimentacaoItem é pai de MaterialMovimentacao. Sendo assim ele não sabe nada de MaterialMovimentacao. E sim MaterialMovimentacao conhece MovimentacaoItem.

Por isso, para mim, seu código não funfa.

Abraço.

Orlando.Neto
Rafael_Leal:
[code]

MovimentacaoItem é pai de MaterialMovimentacao. Sendo assim ele não sabe nada de MaterialMovimentacao. E sim MaterialMovimentacao conhece MovimentacaoItem.

Por isso, para mim, seu código não funfa.

Abraço.

Obrigado a todos pelas sugestões,
Rafael, porém o método private Set seriaisSugeridos; está na classe MovimentacaoItem, com o seu método get public, logo tanto o MaterialMovimentacao quanto o ComponenteMovimentacao enxergam normalmente ele,
tanto que se eu tentar acessar o método getSeriasSugeridos pelas classes filhas, o método é acessado normalmente.

A questão é quando eu tento acessar ele com alguem que extenda de MovimentacaoItem (List) , que vem o problema e o Set não vem tipado.

R

Orlando.Neto:
Rafael_Leal:

MovimentacaoItem é pai de MaterialMovimentacao. Sendo assim ele não sabe nada de MaterialMovimentacao. E sim MaterialMovimentacao conhece MovimentacaoItem.

Por isso, para mim, seu código não funfa.

Abraço.

Obrigado a todos pelas sugestões,
Rafael, porém o método private Set seriaisSugeridos; está na classe MovimentacaoItem, com o seu método get public, logo tanto o MaterialMovimentacao quanto o ComponenteMovimentacao enxergam normalmente ele,
tanto que se eu tentar acessar o método getSeriasSugeridos pelas classes filhas, o método é acessado normalmente.

A questão é quando eu tento acessar ele com alguem que extenda de MovimentacaoItem (List<? extends MovimentacaoItem>) , que vem o problema e o Set não vem tipado.

Eu entendi.
Porém a API só valida se a lista é tipada do tipo List<? extends MovimentacaoItem> items. Isso não garante a Assinatura de Estrutura de Classe para o copilador. Por isso a minha sugestão é:

Coloque a assinatura do método abaixo na Inteface ItemMovimentacao:

private void extractSerial(List<? extends ItemMovimentacao> items, ModelAndView modelAndView, String type)

E coloque o @Override no metédo implementado na Classe MovimentacaoItem e mude a lista para o tipo da interface ItemMovimentacao;

Dai ASSIM você tá explicitado para o copilador que todos os objetos que povoam a lista dever a mesma estrutura de métodos e tipo. Pois quando você fala que o pode ser qualquer um que extenda MovimentacaoItem ainda sim a VM não pode usar os atribitos e métodos privados em seu método. Por isso ele tipa para super classe Object para forçar a assinatura padrão para copilador. (Isso é minha opinião… mas pode vir alguém e desmintir)

Abraço!

Orlando.Neto

Rafael_Leal:
Orlando.Neto:
Rafael_Leal:

MovimentacaoItem é pai de MaterialMovimentacao. Sendo assim ele não sabe nada de MaterialMovimentacao. E sim MaterialMovimentacao conhece MovimentacaoItem.

Por isso, para mim, seu código não funfa.

Abraço.

Obrigado a todos pelas sugestões,
Rafael, porém o método private Set seriaisSugeridos; está na classe MovimentacaoItem, com o seu método get public, logo tanto o MaterialMovimentacao quanto o ComponenteMovimentacao enxergam normalmente ele,
tanto que se eu tentar acessar o método getSeriasSugeridos pelas classes filhas, o método é acessado normalmente.

A questão é quando eu tento acessar ele com alguem que extenda de MovimentacaoItem (List<? extends MovimentacaoItem>) , que vem o problema e o Set não vem tipado.

Eu entendi.
Porém a API só valida se a lista é tipada do tipo List<? extends MovimentacaoItem> items. Isso não garante a Assinatura de Estrutura de Classe para o copilador. Por isso a minha sugestão é:

Coloque a assinatura do método abaixo na Inteface ItemMovimentacao:

private void extractSerial(List<? extends ItemMovimentacao> items, ModelAndView modelAndView, String type)

E coloque o @Override no metédo implementado na Classe MovimentacaoItem e mude a lista para o tipo da interface ItemMovimentacao;

Dai ASSIM você tá explicitado para o copilador que todos os objetos que povoam a lista dever a mesma estrutura de métodos e tipo. Pois quando você fala que o pode ser qualquer um que extenda MovimentacaoItem ainda sim a VM não pode usar os atribitos e métodos privados em seu método. Por isso ele tipa para super classe Object para forçar a assinatura padrão para copilador. (Isso é minha opinião… mas pode vir alguém e desmintir)

Abraço!

hmmm


Porém a API só valida se a lista é tipada do tipo List<? extends MovimentacaoItem> items. Isso não garante a Assinatura de Estrutura de Classe para o copilador.

Não sabia que funcionava assim, vou dar uma olhada nisso aqui e posto aqui.

Obrigado Rafael pela explicação, abraços.

R

Orlando.Neto:
Rafael_Leal:
Orlando.Neto:
Rafael_Leal:

MovimentacaoItem é pai de MaterialMovimentacao. Sendo assim ele não sabe nada de MaterialMovimentacao. E sim MaterialMovimentacao conhece MovimentacaoItem.

Por isso, para mim, seu código não funfa.

Abraço.

Obrigado a todos pelas sugestões,
Rafael, porém o método private Set seriaisSugeridos; está na classe MovimentacaoItem, com o seu método get public, logo tanto o MaterialMovimentacao quanto o ComponenteMovimentacao enxergam normalmente ele,
tanto que se eu tentar acessar o método getSeriasSugeridos pelas classes filhas, o método é acessado normalmente.

A questão é quando eu tento acessar ele com alguem que extenda de MovimentacaoItem (List<? extends MovimentacaoItem>) , que vem o problema e o Set não vem tipado.

Eu entendi.
Porém a API só valida se a lista é tipada do tipo List<? extends MovimentacaoItem> items. Isso não garante a Assinatura de Estrutura de Classe para o copilador. Por isso a minha sugestão é:

Coloque a assinatura do método abaixo na Inteface ItemMovimentacao:

private void extractSerial(List<? extends ItemMovimentacao> items, ModelAndView modelAndView, String type)

E coloque o @Override no metédo implementado na Classe MovimentacaoItem e mude a lista para o tipo da interface ItemMovimentacao;

Dai ASSIM você tá explicitado para o copilador que todos os objetos que povoam a lista dever a mesma estrutura de métodos e tipo. Pois quando você fala que o pode ser qualquer um que extenda MovimentacaoItem ainda sim a VM não pode usar os atribitos e métodos privados em seu método. Por isso ele tipa para super classe Object para forçar a assinatura padrão para copilador. (Isso é minha opinião… mas pode vir alguém e desmintir)

Abraço!

hmmm


Porém a API só valida se a lista é tipada do tipo List<? extends MovimentacaoItem> items. Isso não garante a Assinatura de Estrutura de Classe para o copilador.

Não sabia que funcionava assim, vou dar uma olhada nisso aqui e posto aqui.

Obrigado Rafael pela explicação, abraços.

Aproposito… falei uma besteira…

O método seria…

@Override
public List<SerialModel> getSeriaisSugeridos(){
return lista;
}

da classe MovimentacaoItem

public List<SerialModel> getSeriaisSugeridos();

Na interface ItemMovimentacao

E mudar a assinatura do seu método…

private void extractSerial(List<? extends ItemMovimentacao> items, ModelAndView modelAndView, String type)
Criado 10 de abril de 2012
Ultima resposta 11 de abr. de 2012
Respostas 6
Participantes 3