A biblioteca de classes padrão do Java consiste em milhares de classes e outros tipos de referência. Apesar das diferenças em suas capacidades, cada um desses tipos estende direta ou indiretamente o Object aula. Juntos, eles formam uma enorme hierarquia de herança.

A primeira metade deste tutorial introduziu os fundamentos da herança em Java. Você aprendeu como usar Java extends e super palavras-chave para derivar uma classe filha de uma classe pai, invocar construtores e métodos de classe pai, substituir métodos e muito mais. Agora, voltaremos nosso foco para a nave-mãe da hierarquia de herança de classes Java, java.lang.Object.

Estudo Object e seus métodos lhe darão uma compreensão mais funcional da herança Java e como ela funciona em seus programas.

O que você aprenderá neste tutorial Java

  • Tudo sobre Object: a superclasse do Java
  • Como estender o objeto: um exemplo
  • O que o método getClass() do Java faz
  • O que o método clone() do Java faz
  • O que o método equals() do Java faz
  • O que o método finalize() do Java faz
  • O que o método hashCode() do Java faz
  • O que o método toString() do Java faz
  • O que os métodos wait() e notify() do Java fazem
download

Baixe o código-fonte de aplicativos de exemplo neste tutorial. Criado por Jeff Friesen.

Tudo sobre Object: a superclasse do Java

Object é a classe raiz, ou superclasse final, de todas as outras classes Java. Armazenado no java.lang pacote, Object declara os seguintes métodos, que todas as outras classes herdam:

  • protected Object clone()
  • boolean equals(Object obj)
  • protected void finalize()
  • Class> getClass()
  • int hashCode()
  • void notify()
  • void notifyAll()
  • String toString()
  • void wait()
  • void wait(long timeout)
  • void wait(long timeout, int nanos)

Uma classe Java herda esses métodos e pode substituir qualquer método que não esteja declarado final. Por exemplo, o não-final toString() método pode ser substituído, enquanto o método final wait() métodos não podem.

Veremos cada um desses métodos e como você pode usá-los para executar tarefas especiais no contexto de suas classes Java. Primeiro, vamos considerar as regras e mecanismos básicos para Object herança.

Como estender o objeto: um exemplo

Uma classe pode estender explicitamente Objectconforme demonstrado na Listagem 1.

Listagem 1. Estendendo explicitamente o objeto

public class Employee extends Object
{
   private String name;

   public Employee(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return name;
   }

   public static void main(String() args)
   {
      Employee emp = new Employee("John Doe");
      System.out.println(emp.getName());
   }
}

Como você pode estender no máximo uma outra classe (lembre-se da Parte 1 que Java não suporta herança múltipla baseada em classe), você não é forçado a estender explicitamente Object; caso contrário, você não poderia estender nenhuma outra classe. Portanto, você estenderia Object implicitamente, conforme demonstrado na Listagem 2.

Listagem 2. Estendendo Objeto Implicitamente

public class Employee
{
   private String name;

   public Employee(String name)
   {
      this.name = name;
   }

   public String getName()
   {
      return name;
   }

   public static void main(String() args)
   {
      Employee emp = new Employee("John Doe");
      System.out.println(emp.getName());
   }
}

Compile a Listagem 1 ou Listagem 2 da seguinte maneira:

javac Employee.java

Execute o aplicativo resultante:

java Employee

Você deve observar a seguinte saída:

John Doe

O que getClass() do Java faz

O getClass() O método retorna a classe de tempo de execução de qualquer objeto no qual ele é chamado. O classe de tempo de execução é representado por um Class objeto, que se encontra no java.lang pacote. Class também é o ponto de entrada para a API Java Reflection, que um aplicativo Java usa para aprender sobre sua própria estrutura.

O que o método clone() do Java faz

O clone() O método cria e retorna uma cópia do objeto no qual é chamado. Porque clone()O tipo de retorno de é Objecta referência do objeto que clone() os retornos devem ser convertidos para o tipo real do objeto antes de atribuir essa referência a uma variável do tipo do objeto. O código na Listagem 3 demonstra a clonagem.

Listagem 3. Clonando um objeto

class CloneDemo implements Cloneable
{
   int x;

   public static void main(String() args) throws CloneNotSupportedException
   {
      CloneDemo cd = new CloneDemo();
      cd.x = 5;
      System.out.println("cd.x = " + cd.x);
      CloneDemo cd2 = (CloneDemo) cd.clone();
      System.out.println("cd2.x = " + cd2.x);
   }
}

Listagem 3 CloneDemo classe implementa o Cloneable interface, que se encontra no java.lang pacote. Cloneable é implementado pela classe (através do implements palavra-chave) para evitar Objectde clone() método de lançar uma instância do CloneNotSupportedException classe (também encontrada em java.lang).

CloneDemo declara um único intcampo de instância baseado em nome nomeado x e um main() método que exercita esta classe. main() é declarado com um throws cláusula que passa CloneNotSupportedException aumentar a pilha de chamadas de método.

main() primeiras instanciações CloneDemo e inicializa a cópia da instância resultante de x para 5. Em seguida, ele gera a instância x valor e chamadas clone() nesta instância, lançando o objeto retornado para CloneDemo antes de armazenar sua referência. Finalmente, ele gera o clone x valor do campo.

Compilar Listagem 3 (javac CloneDemo.java) e execute o aplicativo (java CloneDemo). Você deve observar a seguinte saída:

cd.x = 5
cd2.x = 5

Substituindo clone()

Não precisamos substituir clone() no exemplo anterior porque o código que chama clone() está localizado na classe que está sendo clonada (CloneDemo). Se a chamada para clone() estavam localizados em uma classe diferente, então você precisaria substituir clone().

Porque clone() é declarado protectedvocê receberá um “clone protegeu o acesso no objeto” mensagem se você não a substituiu antes de compilar a classe. A Listagem 4 é uma versão refatorada da Listagem 3 que demonstra a substituição clone().

Listagem 4. Clonando um objeto de outra classe

class Data implements Cloneable
{
   int x;

   @Override
   public Object clone() throws CloneNotSupportedException
   {
      return super.clone();
   }
}

class CloneDemo
{
   public static void main(String() args) throws CloneNotSupportedException
   {
      Data data = new Data();
      data.x = 5;
      System.out.println("data.x = " + data.x);
      Data data2 = (Data) data.clone();
      System.out.println("data2.x = " + data2.x);
   }
}

A Listagem 4 declara um Data classe cujas instâncias devem ser clonadas. Data implementa o Cloneable interface para evitar CloneNotSupportedException de ser jogado quando o clone() método é chamado. Em seguida, declara intcampo de instância baseado em xe substitui o clone() método. O clone() método executa super.clone() para chamar sua superclasse (ou seja, Objectde) clone() método. A substituição clone() método identifica CloneNotSupportedException em seu throws cláusula.

A Listagem 4 também declara um CloneDemo classe que: instancia Datainicializa seu campo de instância, gera o valor do campo de instância, clona o Data objeto e gera seu valor de campo de instância.

Compilar a listagem 4 (javac CloneDemo.java) e execute o aplicativo (java CloneDemo). Você deve observar a seguinte saída:

data.x = 5
data2.x = 5

Clonagem superficial

Clonagem superficial (também conhecida como cópia superficial) refere-se à duplicação dos campos de um objeto sem duplicar quaisquer objetos referenciados nos campos de referência desse objeto (se houver algum campo de referência). As listagens 3 e 4 demonstraram, na verdade, clonagem superficial. Cada um dos cd-, cd2-, data-, e data2-campos referenciados identifica um objeto que possui sua própria cópia do int-baseado x campo.

A clonagem superficial funciona bem quando todos os campos são do tipo primitivo e (em muitos casos) quando qualquer campo de referência se refere a imutável objetos (inalteráveis). No entanto, se algum objeto referenciado for mutável, as alterações feitas em qualquer um desses objetos poderão ser vistas pelo objeto original e seu(s) clone(s). A Listagem 5 demonstra.