Início‎ > ‎

Usar objetos imutáveis

Em Java, as variáveis representam referências para objetos, e não os objetos em si. Com isso, duas variáveis diferentes podem referenciar o mesmo objeto. Neste caso, alterações feitas no objeto através de uma das variáveis poderão ser vistas através da segunda variável.

O mesmo acontece no caso dos objetos retornados por um método. Neste caso, o valor retornado é uma referência para o objeto. Assim, o chamador de um método que recebe um objeto (na verdade uma referência para um objeto) como resultado pode alterar os valores armazenados neste objeto. Se o objeto retornado for posteriormente alterado, este pode entrar em um estado inconsistente, levando a erros ou falhas de segurança.

Para evitar este problema, os objetos retornados por métodos devem ser imutáveis (seu estado não pode ser alterado depois que o objeto foi criado, o melhor exemplo em Java são Strings) - ou, caso não seja possível, devem ser retornadas cópias dos objetos. Se os objetos retornados forem imutáveis, não há necessidade de copiá-los.

A seguir, apresentamos um exemplo de objeto mutável e dos problemas que podem ocorrer quando um objeto mutável é retornado por um método:

class Exposed{
  private int id;
  private String name;
  public Exposed(){
  }
  public Exposed(int id, String name){
    this.id = id;
    this.name = name;
  }
  public int getId(){
    return id;
  }
  public String getName(){
    return name;
  }
  public void setId(int id){
    this.id=id;
  }
  public void setName(String name){
    this.name = name;
  }
  public void display(){
    System.out.println("Id = "+ id + " Name = "+ name);
  }
}

public class Exp12{
  private Exposed exposedObj = new Exposed(1,"Harry Porter");
  public Exposed getExposedObj(){
    return exposedObj; //retorna uma referencia ao objeto.
  }
  public static void main(String[] args){
    Exp12 exp12 = new Exp12();
    exp12.getExposedObj().display();
    Exposed exposed = exp12.getExposedObj();
    exposed.setId(10);
    exposed.setName("Hacker");
    exp12.getExposedObj().display();
  }
}

Este código demonstra que um objeto (Exposed) pode ser alterado através de uma referência retornada por um método da classe Exp12. Como esta classe sempre retorna um referência ao mesmo objeto, as alterações feitas no estado do objeto pela função main() se refletem nas próximas chamadas ao método getExposedObj().

Para evitar que isto aconteça, basta que seja sempre retornada uma referência a uma cópia do objeto corrente, conforme o código abaixo:

public Exposed getExposedObj(){
  return new Exposed(exposedObj.getId(),exposedObj.getName());
}

Comments