Dúvida em stanceof

11 respostas
T
interface Fish { }

class Perch implements Fish { }

class Walleye extends Perch { }

class Bluegill { }

public class Fisherman
{
	public static void main(String[] args) {

		Fish f = new Walleye();
		Walleye w = new Walleye();
		Bluegill b = new Bluegill();


		if(f instanceof Perch) System.out.print("f-p ");
		if(w instanceof Fish) System.out.print("w-f ");
		if(b instanceof Fish) System.out.print("b-f ");
	}
}

Pra mim era para dar erro na linha 20, já que é impossível b ser uma instância de Fish. Alguém pode me explicar porque não gera erro de compilação na linha 20?

11 Respostas

renzonuccitelli

O instanceof serve só para perguntar se o objeto é instancia de uma determinada classe. Logo não teria porque da erro, simplesmente o print da linha 20 não será impresso.

T

Vc quer dizer que ele não funciona com interfaces?

renzonuccitelli

Serve com interfaces tb. Se a classe implementar a interface, ou uma de suas ancestrais implementar, o instanceof retorna true.

T

Ainda não entendi...

Tipo, o seguinte código gera erro de compilação:

class Whatever{}

class Teste
{
        public static void main(String...$){
                
                 Whatever w = new Whatever();
                 if(w instanceof Object) ; //ok, compila normal ate aqui
                 if(w instanceof String) ;//nao compila! O compilador detecta que w não pode ser filha/pai de String sobre NENHUMA HIPOTESE!
        }
}

Por que entao no meu primeiro exemplo o compilador tambem nao detecta?

V

porq no primeiro exemplo vc está utilizando interfaces…
quando vc compara com uma interface não dará erro de compilação porq a classe poderá estar implementando a interface de forma indireta…

andeb

vmsb11:
porq no primeiro exemplo vc está utilizando interfaces…
quando vc compara com uma interface não dará erro de compilação porq a classe poderá estar implementando a interface de forma indireta…

Não é bem isso, isso aqui também não compila:

String o = new String(); if (o instanceof Fish) System.out.println();

A resposta é simples e você já disse, não compila por que String em nenhum hipótese pode ser um Fish, afinal ele é final…
Não tem como mudar a árvore, mude o Bluegill para final também que você vai ter o erro de compilação.

O exemplo abaixo é válido e o instance of retorna true.

public final class BluegillChild extends Bluegill implements Fish {}

public class Fisherman {

    public static void main(String[] args) {
        Bluegill b = new BluegillChild();
        if (b instanceof Fish) System.out.print("b-f ");
    }

}

Agora sim, através de polimorfismo podemos dizer que Bluegill é sim um Fish.

Ok?

T

andeb, quer dizer que só ocorre erros de compilação no instanceof quando vc está fazendo qualquerReferenciaDeQualquerClasseSejaEstaFinalOuNao instanceof AlgumaCoisaFinalAqui ou algumacoisafinalaqui instanceof QualquerClasseOuInterfaceSejaElaFinalOuNao ??? É isso? :shock:

andeb

Nesse caso, a recíproca é verdadeira hehe
Não importa em qual lado vai estar o final, o compilador vai acusa como erro quando não for possível, em hipótese nenhuma, que a condição seja verdadeira. Quando uma classe não é final, ela pode ser extentida e/ou implementado por outra que faça a condição ser verdadeira.

L

Imagine a seguinte situação:

TipoQualquer t = ...
if (t instanceof MinhaClasse) {
   //
}

Só vai dar erro de compilação quando o tipo da variável t não for “pai” (ou “avô”, ou “bisavô”…) de MinhaClasse, porque aí, é obvio que não há a possiblidade de ser verdadeiro. Ou melhor dizendo: é erro quando as classes TipoQualquer e MinhaClasse não são da mesma árvore da hierarquia de classes.

Agora, com interfaces, a coisa muda de figura, porque não existe qualquer relação de hierarquia entre classe e interface. Suponha a seguinte situação:

TipoQualquer t = ...
if (t instanceof MinhaInterface) {
   //
}

Talvez TipoQualquer não implemente MinhaInterface. Mas quem garante que filhos de TipoQualquer (que podem ser atribuídos à variável t) não resolva implementar essa interface? Ninguém! Por isso que o compilador não pode fazer nada! No primeiro exemplo ali de cima, não tem como um filho de TipoQualquer herdar de MinhaClasse, não existe herança múltipla!

T

Leonardo3001, por esse seu racioncínio, não tem como afirmar que sempre que você estiver fazendo x instanceof InterfaceQualquerAqui e x se referir à uma classe não final, não iremos ter um erro de compilação?

L

O que estou dizendo é: se eu estiver fazendo

x instanceof InterfaceQualquerAqui

, onde x refere-se a uma classe não-final, nunca iremos ter erro de compilação.

Criado 13 de fevereiro de 2010
Ultima resposta 13 de fev. de 2010
Respostas 11
Participantes 5