dúvida sobre instanceof

5 respostas
marciolx

isso me deixou confuso:

porque o código abaixo não compila, gerando o erro:

6.                 System.out.println (m instanceof Collection);
                                            <--------------------->
*** Error: The type of the left-side expression, "java/util/Map", cannot possibl
y be an instance of type "java/util/Collection".
import java.util.*;

public class TCol9 {
	public static void main (String [] args) {
		Map m = new HashMap();
		System.out.println (m instanceof Collection);
	}
}

e se eu mudar a declaração:

Map m = new HashMap();

para:

AbstractMap m = new HashMap();

ele compila?

5 Respostas

C

import java.util.*;

public class Teste {
public static void main(String[] args) {
	Map m = new HashMap();
	System.out.println(m instanceof Collection);
}
 }

 Esse código compilou e rodou no Eclipse 2.1, e não tem porque não compilar.
Paulo_Silveira

porque Map nao extends a interface Collection, entao NUNCA vai ser possivel isso retornar true.

ricardolecheta

tudo bem que o Map não extendes a Colection, mas não compilar por causa disso?

marciolx

Bom, eu andei procurando na JLS e o capítulo 5 versículo 5 diz o seguinte (com relação à conversão de tipos):

no caso seria S instanceof T, ou traduzindo para o código de exemplo da minha dúvida: referência de classe abstrata instanceof interface

Então não ocorre o erro de compilação porque mesmo AbstractMap não tendo nada a ver com Collection, uma subclasse dela poderia implementar a interface Collection, portanto o compilador não tem condições de dizer se o cast está correto ou não e deixa passar.

Eu achava que AbstractMap poderia estender AbstractCollection, aí as coisas ficariam claras, mas uma rápida olhada na API mostra que isso não é verdade. A razão portanto deste código compilar sem erros é que o compilador não pode assumir nada com relação à classe Abstrata porque uma subclasse dela poderia implementar a interface.

Outro exemplo que compila baseado nesta explicação:

abstract class ABase {}

class AChild extends ABase {}

public class TInst1 {
	public static void main (String [] args) {
		System.out.println ( new AChild () instanceof java.util.Collection );
	}
}

No exemplo acima, se eu fosse tentar um cast de AChild para Collection, resultaria em uma runtime exception ClassCastException, mas como eu estou testando com o operador instanceof, apenas imprime false, sem lançar excessão. Note que AChild, assim como AbstractMap não tem nada a ver com Collection.

marciolx

tudo bem que o Map não extendes a Colection, mas não compilar por causa disso?

No caso de interface instanceof interface, se ambas tiverem o mesmo método mas com tipo de retorno diferente, não compila:

import java.util.*;

interface I1 {
	public void add (Object o);
}


class Child implements I1 {
	public void add (Object o) { }
}

public class TInst2 {
	public static void main (String [] args) {
		I1 i = new Child();
		System.out.println (i instanceof Collection);
	}
}

O método add da interface I1 tem o tipo de retorno void e entra em conflito com o método add da interface Collection que tem o tipo de retorno boolean.
Assim, se eu mudar o código para:

import java.util.*;

interface I1 {
}


class Child implements I1 {
}

public class TInst2 {
	public static void main (String [] args) {
		I1 i = new Child();
		System.out.println (i instanceof Collection);
	}
}

aí compila sem problemas…

haja neurônios pra lembrar de tudo isso…

Criado 15 de setembro de 2003
Ultima resposta 16 de set. de 2003
Respostas 5
Participantes 4