CodeGym /Blogue Java /Random-PT /Instância Java do Operador
John Squirrels
Nível 41
San Francisco

Instância Java do Operador

Publicado no grupo Random-PT
Oi! Hoje falaremos sobre o operador instanceof , consideraremos exemplos de como ele é usado e abordaremos alguns aspectos de como ele funciona :) Você já encontrou esse operador nos níveis iniciais do CodeGym. Você se lembra por que precisamos disso? Se não, não se preocupe. Vamos lembrar juntos. O operador instanceof é necessário para verificar se um objeto referenciado por uma variável X foi criado com base em alguma classe Y. Isso parece simples. Por que voltamos a este tópico? Em primeiro lugar, porque agora você está bem familiarizado com o mecanismo de herança de Java e os outros princípios da POO. O operador instanceof agora ficará muito mais claro e veremos exemplos mais avançados de como ele é usado. Vamos!Como funciona o operador instanceof - 1Você provavelmente se lembra de que o operador instanceof retorna true se a verificação for verdadeira ou false se a expressão for falsa. Conseqüentemente, geralmente ocorre em todos os tipos de expressões condicionais ( if…else ). Vamos começar com alguns exemplos mais simples:

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
O que você acha que será exibido no console? Bem, é óbvio aqui. :) O objeto x é um Integer, então o resultado será true . Saída do console: True Vamos tentar verificar se é uma String :

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
Ocorreu um erro. E preste atenção: o compilador gerou o erro antes de executar o código! Ele viu imediatamente que Integer e String não podem ser convertidos automaticamente um no outro e não estão relacionados por herança. Conseqüentemente, um objeto Integer não é criado com base em String . Isso é conveniente e ajuda a evitar erros estranhos de tempo de execução, então o compilador nos ajudou aqui :) Agora vamos tentar considerar exemplos que são mais difíceis. Já que mencionamos herança, vamos trabalhar com o seguinte pequeno sistema de classes:

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
Já sabemos como instanceof se comporta quando verificamos se um objeto é uma instância de uma classe, mas o que acontece se considerarmos o relacionamento pai-filho? Por exemplo, o que você acha que essas expressões renderão:

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
Saída: Verdadeiro Falso A principal questão que precisa ser respondida é exatamente como instanceof interpreta 'objeto criado com base em uma classe'? ' cat instanceof Animal ' avalia como true , mas certamente podemos encontrar falhas nessa redação. Por que um objeto Cat é criado com base na classe Animal ? Não é criado com base apenas em sua própria classe? A resposta é bastante simples e você já deve ter pensado nisso. Lembre-se da ordem em que os construtores são chamados e as variáveis ​​são inicializadas ao criar um objeto. Já cobrimos esse tópico no artigo sobre construtores de classe . Aqui está um exemplo dessa lição:

public class Animal {

   String brain = "Initial value of brain in the Animal class";
   String heart = "Initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("Animal base class constructor is running");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("Current value of static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in the Animal class = " + this.brain);
       System.out.println("Current value of heart in the Animal class = " + this.heart);
       System.out.println("Have the variables of the Cat class already been initialized?");
       System.out.println("Current value of static variable catCount = " + Cat.catCount);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor is done!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The Cat class constructor has started (The Animal constructor already finished)");
       System.out.println("Current value of static variable catCount = " + catCount);
       System.out.println("Current value of tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value of tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
E se você executá-lo no IDE, a saída do console será semelhante a esta: Animal base class constructor is running As variáveis ​​da classe Animal já foram inicializadas? Valor atual da variável estática animalCount = 7700000 Valor atual do cérebro na classe Animal = Valor inicial do cérebro na classe Animal Valor atual do coração na classe Animal = Valor inicial do coração na classe Animal Já tem as variáveis ​​da classe Gato foi inicializado? Valor atual da variável estática catCount = 37 O construtor da classe base Animal está pronto! Valor atual de brain = Brain Valor atual heart = Heart O construtor da classe cat foi iniciado (o construtor Animal já terminou) Valor atual da variável estática catCount = 37 Valor atual de tail = Valor inicial de tail na classe Cat Valor atual de tail = Cauda Agora você se lembra? :) O construtor da classe base, se houver uma classe base, é sempre chamado primeiro ao criar um objeto. O operador instanceof é guiado por esse princípio ao tentar determinar se um objeto A foi criado com base em uma classe B. Se o construtor da classe base for chamado, não haverá dúvida. Com a segunda verificação, tudo fica mais simples:

System.out.println(cat instanceof MaineCoon);
O construtor MaineCoon não foi chamado quando o objeto Cat foi criado, o que faz sentido. Afinal, MaineCoon é um descendente de Cat , não um ancestral. E não é um modelo para Cat . Ok, acho que estamos claros sobre isso. Mas o que acontece se fizermos isso?:

public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
Hmm... agora ficou mais difícil. Vamos conversar sobre isso. Temos uma variável Cat à qual atribuímos um objeto MaineCoon . A propósito, por que isso funciona? Podemos fazer isso, certo? Sim, nós podemos. Afinal, todo MaineCoon é um gato. Se isso não estiver totalmente claro, lembre-se do exemplo de alargamento de tipos primitivos:

public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
O número 1024 é curto : cabe facilmente em uma variável longa , pois há bytes suficientes para acomodá-la (lembra do exemplo com os bonecos?). Um objeto descendente sempre pode ser atribuído a uma variável ancestral. Por enquanto, apenas lembre-se disso, e nas próximas lições analisaremos como isso funciona. Então, qual é a saída do nosso exemplo?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
O que será verificado pelo instanceof ? nossa variável Cat ou nosso objeto MaineCoon ? A resposta é esta pergunta é realmente simples. Você só precisa ler a definição do operador novamente: O operador instanceof é necessário para verificar se um objeto referenciado por uma variável X foi criado com base em alguma classe Y. O operador instanceof testa a origem de um objeto, não o tipo de variável. Assim, neste exemplo, nosso programa exibirá true em ambos os casos: temos um objeto MaineCoon . Obviamente, foi criado com base na classe MaineCoon , mas foi criado com base na classe Catclasse pai também!
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION