[RESOLVIDO] Curiosidade: Bug no uso de Collections ou bug na API Collections? Ou estou ficando louco

4 respostas
eltonads

Olá pessoal do GUJ.

Esses dias durante o meu trabalho, deparei-me com um trecho de código que estava causando bugs no projeto que estou desenvolvendo.
Até aí nada de novo, o problema é que nunca me deparei com um erro como esse… Como acho que estou ficando louco (pois já trabalho com Java há muito tempo) e como não encontrei nenhuma explicação lógica para o erro (a não ser “Ou eu estou errado… ou o Java está errado”), peço a ajuda e/ou opinião de vocês sobre o caso.

Abaixo segue um pequeno teste unitário que desenvolvi que aborda o problema:

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import junit.framework.TestCase;

public class PolimorphismTest extends TestCase {
	public void testCollectionPointerBug() throws Exception {
		Collection<Object> collectionPointer = new LinkedList<Object>();
		List<Object> listPointer = (List<Object>) collectionPointer;

		listPointer.add(new Object());
		assertEquals(1, listPointer.size());
		listPointer.remove(0);
		assertEquals(0, listPointer.size());

		collectionPointer.add(new Object());
		assertEquals(1, collectionPointer.size());
		collectionPointer.remove(0);
		assertEquals(0, collectionPointer.size()); // <- Teste falha!!!
	}
}

Agora a pergunta… Por causa do polimorfismo, não deveria ser o mesmo resultado? A única diferença entre as duas operações são as referências… O objeto em teoria não deveria executar a mesma operação? Alguém tem o telefone de um psiquiatra?

Agradeço desde já!

Att.,

4 Respostas

mario.fts

não é um bug. se vc olhar a API de Collection (Interface) vai ver que só existe o método “remove(Object o)”, que remove o objeto passado por parametro, se ele existir na coleção. Não existe o método “remove(int index)”, que só existe na interface List, que remove o objeto no indice passado como parametro.

no caso, o que acontece é q o 0 passado na segunda chamada de remove é convertido para um Integer wrapper, que como não existe na lista, não é removido. logo a lista fica com tamanho = 1.

espero ter sido claro, num sou muito bom em explicações… :lol:

eltonads

Po cara… pior que foi muito claro sim… Agora vi a “pegadinha” que eu não tava pescando…
E olha que debugando isso ontem, cheguei a ver que dois métodos diferentes eram chamados, mas realmente não reparei no parâmetro passado! tsc tsc…
Acho que preciso mesmo marcar o tal psiquiatra…

Valeu pela ajuda!

Att.,

E

Collection.remove não aceita um parâmetro “int”, até porque você pode ter coleções não-indexadas, como Set (HashSet, TreeSet).
É que houve um “boxing” em collectionPointer.remove que você não enxergou.

import java.util.*;

 public class TesteCollection {  
     public static void main (String[] args) {  
         Collection<Object> collectionPointer = new LinkedList<Object>();  
         List<Object> listPointer = (List<Object>) collectionPointer;  
   
         listPointer.add(new Object());  
         System.out.println (listPointer.size());  
         System.out.println (listPointer);
         listPointer.remove(0);  
         System.out.println (listPointer.size());  
         System.out.println (listPointer);
   
         collectionPointer.add(new Object());  
         System.out.println (collectionPointer.size());  
         System.out.println (collectionPointer);
         // Não existe Collection.remove (int), apenas Collection.remove (Object). 
         collectionPointer.remove(0);  
         System.out.println (collectionPointer.size()); 
         System.out.println (collectionPointer);
         collectionPointer.remove(Integer.valueOf(0));  // equivale à linha collectionPointer.remove (0);
         System.out.println (collectionPointer.size()); 
         System.out.println (collectionPointer);
     }  
 }
Marky.Vasconcelos

Lists tem indexes.
Collections não.

Nossa… eu abro varias abas pra depois olhar… depois que posto vejo que voce já tem as respostas.

Criado 23 de setembro de 2009
Ultima resposta 23 de set. de 2009
Respostas 4
Participantes 4