Marcador de interface em Java é uma interface sem campos ou métodos contidos nele. Ele é usado para transmitir a JVM que a classe implementa uma interface desta categoria terá um comportamento especial.

Assim, uma interface vazia em Java é chamada marcador de interface. Marcador de interface também é chamado de interface de tag por alguns gurus Java. Em Java, temos os principais marcadores de interface abaixo:

  • Interface Serializable
  • Interface Cloneable
  • Interface Remote
  • Interface ThreadSafe

O marcador de interface pode ser descrito como um padrão de design que é utilizado por muitas línguas para fornecer informações em tempo de execução sobre os objetos. Ele fornece uma maneira de associar metadados com a classe em que o suporte a linguagem não está disponível.

Uma interface normal especifica a funcionalidade que uma classe de implementação deve implementar. Mas uma interface de marcador não segue esse padrão. Por outro lado, a implementação da classe define o comportamento. Existem algumas interfaces híbridas que atuam como um marcador de interface, juntamente com alguns métodos. Mas este tipo de projeto é confuso se não for tratado com cuidado.

Uso de marcador de interface em Java:

Marcador de Interface em Java, como por exemplo, Serializable, Clonnable and Remote é usado para indicar algo para compilador ou a JVM que a classe que implementar qualquer um desses teria um comportamento especial. Assim, se a JVM vê uma classe que implemente a interface Serializable, é feito alguma operação especial sobre ele e escreve o estado do objeto no stream objeto. Este fluxo de objeto é, então, disponível para ser lido por outra JVM. Da mesma forma, se a JVM descobre que uma classe é a implementação da interface Clonnable, ele realiza uma operação especial, a fim de apoiar a clonagem. A mesma teoria vale para RMI e da interface Remote. Esta indicação (a JVM) também pode ser feita usando um sinalizador booleano ou uma variável String dentro da classe.

Além de usar o marcador de interface para marcar uma classe como serializable ou clonnable, também podemos ter o nosso próprio marcador de interface, que é uma boa maneira de logicamente separar o código e também de termos a nossa própria ferramenta para executar uma operação de pré-processamento. É muito útil para o desenvolvimento de estruturas ou APIs, por exemplo, Struts ou Spring.

Com a introdução de anotações no Java 5, as anotações tornaram-se uma escolha melhor para se usar marcadores de interface.

A interface Thread Safe é um marcador de interface que pode ser usado para se comunicar com outros desenvolvedores que as classes que implementam esta interface marcadora dá garantia thread-safe e qualquer modificação não deve violar isso. Marcador de interface também ajuda a cobertura de código ou uma ferramenta de análise de código para encontrar bugs com base no comportamento específico de interfaces marcador. Aqui também as anotações são a melhor escolha. @ Threadsafe parece muito melhor do que a implementação da interface Thread Safe.

Em resumo um marcador de interface em Java é utilizado para indicar algo para o compilador, JVM ou qualquer outra ferramenta, mas anotação é a melhor maneira de fazer o mesmo.

A interface Serializable:

A interface Serializable fornece um mecanismo de serialização de objetos onde um objeto é representado como uma sequência de bytes. Depois que um objeto é serializado e escrito em um arquivo, ele pode ser lido a partir do arquivo e serializado. Desserialização é o processo de leitura do objeto a partir do arquivo e reconstruir o objeto na memória. Todo o processo de serialização e desserialização é independente de JVM. Um objeto serializado por uma JVM pode ser facilmente lido em outra JVM.

Em alto nível, as classes ObjectOutputStream e ObjectInputStream contém métodos para serialização e desserialização de objetos. A classe ObjectOutputStream contém métodos para gravar o objeto em disco. O método mais usado é o writeObject, que segue na listagem abaixo:

Listagem 1: Método writeObject

public final void writeObject(Object x) throws IOException

Listagem 2: Exemplo de classe que implementa Serializable

package com.br.marker.demo;
 
import java.io.Serializable;
import java.util.Date;
 
public class Employee implements Serializable {
 
    /**
     * The seialized version Id
     */
    private static final long serialVersionUID = -3771755785034784363L;
 
    /**
     * The constructor
     */
    public Employee() {
         
    }
     
    // The first name
    private String firstName;
     
    // The last name
    private String lastName;
     
    // The date of joining
    private Date dateOfJoining;
     
    // The department of the employee
    private String department;
     
    // The ecode of the employee
    private int ecode;
 
    /**
     * @return the firstName
     */
    public String getFirstName() {
        return firstName;
    }
 
    /**
     * @param firstName the firstName to set
     */
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
 
    /**
     * @return the lastName
     */
    public String getLastName() {
        return lastName;
    }
 
    /**
     * @param lastName the lastName to set
     */
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
 
    /**
     * @return the dateOfJoining
     */
    public Date getDateOfJoining() {
        return dateOfJoining;
    }
 
    /**
     * @param dateOfJoining the dateOfJoining to set
     */
    public void setDateOfJoining(Date dateOfJoining) {
        this.dateOfJoining = dateOfJoining;
    }
 
    /**
     * @return the department
     */
    public String getDepartment() {
        return department;
    }
 
    /**
     * @param department the department to set
     */
    public void setDepartment(String department) {
        this.department = department;
    }
 
    /**
     * @return the ecode
     */
    public int getEcode() {
        return ecode;
    }
 
    /**
     * @param ecode the ecode to set
     */
    public void setEcode(int ecode) {
        this.ecode = ecode;
    }
 
    /**
     * @return the serialversionuid
     */
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
 
}

Listagem 3: Exemplo de classe que implementa marcador de interface

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
 
import com.br.marker.demo.Employee;
 
public class SerializeDemo {
 
    public SerializeDemo() {
    }
 
    public static void main(String[] args) {
        Employee employee = new Employee();
        employee.setFirstName( "Davi" );
        employee.setLastName( "Costa" );
        employee.setDepartment( "Technical" );
        employee.setEcode(4321);
        try {
            String dojStr = "1984-07-15";
            DateFormat df = new SimpleDateFormat( "yyyy-MM-dd" );
            Date dojDate = null;
            dojDate = df.parse(dojStr);
 
            employee.setDateOfJoining(dojDate);
            FileOutputStream fileOut = new FileOutputStream( "employee.ser" );
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(employee);
            out.close();
            fileOut.close();
        } catch (IOException i) {
            i.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
 
}

No exemplo acima, a classe Employee implementa a interface Serializable. Assim, o objeto employee é escrito em forma de stream. A interface Serializable é útil quando precisamos usar um objeto em diferentes JVMs. Por exemplo, aplicações de várias camadas, onde as diferentes camadas estão em diferentes JVMs.

A interface Cloneable:

Uma interface Cloneable, permite que um desenvolvedor crie um clone de um objeto. A fim de obter o clone de um objeto, é necessário fazer um cast apropriado. Se a classe não está implementando a interface Cloneable, e tentar clonar o objeto temos um CloneNotSupportedException. No processo de clonagem, o construtor não é chamado, em vez disso uma cópia exata do referido objeto é criado. Mas o objeto do qual o clone é criado, deve implementar a interface Cloneable.

Método clone () da classe Object cria e retorna uma cópia do objeto, com a mesma classe e com todos os campos com os mesmos valores. No entanto, Object.clone () lança um CloneNotSupportedException a menos que o objeto é uma instância de uma classe que implementa a interface de Cloneable.

A implementação padrão de Object.clone () executa uma cópia superficial. Se uma classe requer uma cópia profunda ou algum outro comportamento personalizado, ele deve ter seu método clone personalizado () depois de obter a cópia da superclasse.

Conclusão

O marcador de interface em Java é uma interface que não tem qualquer método. O marcador de interface é usado para informar a JVM que as classes de aplicação delas terão um comportamento especial.