Pergunta

Este é um exemplo de cópia defensiva em Java Efetivo.Suponha que esse cenário em minhas questões subjacentes precise de uma cópia defensiva e não possa fazer um comentário solicitando ao cliente que evite a passagem de objetos mutantes.

public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
}

Questões:

  1. O que fazer se Date não tinha um construtor para se absorver, para me tornar mais geral, um objeto é passado sem nenhum mecanismo para se replicar, e tal objeto não nos pertence, ou seja, não podemos alterá-lo de forma alguma?

  2. E se o construtor usasse o parâmetro de tipo como argumento, digamos Period(T object) e T podem ser mutáveis, portanto precisam de cópia defensiva.Não temos ideia do que é T.Como fazer cópia defensiva neste caso?

  3. O que é uma interface é passada onde algumas de suas subclasses possuem um construtor como Date criar um objeto próprio e algumas de suas subclasses não possuem nenhum mecanismo para fazer isso?

  4. Quão profundo devemos copiar defensivamente?Digamos que copiamos um array, mas os elementos do array eram mutáveis?

Foi útil?

Solução

  1. Se todo o seu estado estiver disponível, você poderá extrair seu estado e construir um novo objeto sozinho.Caso contrário, você não poderá fazer nada a respeito, exceto usar truques desagradáveis ​​de reflexão ou serialização.
  2. Se T não for uma instância de uma classe que permita copiar a si mesma, você não poderá fazer nada.
  3. Você não pode fazer nada sobre isso.
  4. Depende.

Ao ler sua pergunta, parece que você gostaria de aplicar o conselho da "cópia defensiva" em todos os lugares.Você não deveria.Na maioria das vezes, o código que usa objetos mutáveis ​​deseja uma referência ao objeto original, e não uma cópia.Especialmente se o que você obtém como argumento for uma instância de uma classe ou interface abstrata.

Você é forçado a fazer uma cópia defensiva de Date porque é um tipo de valor mutável que não deveria ser mutável e não seria se tivesse sido projetado corretamente.Se você promover a imutabilidade para tipos de valor, as cópias defensivas se tornarão desnecessárias.Para tipos sem valor, geralmente você não deseja uma cópia, mas uma referência ao objeto.

Outras dicas

    .
  1. Se você não puder alterar o estado do objeto de qualquer maneira, você não precisa de uma cópia defensiva.
  2. A única coisa que você pode fazer é assumir a implementação provável de t e verificá-los com instance de .
  3. o mesmo que 2.
  4. a seu critério.Se você assumir que a modificação de elementos da matriz pode quebrar seu programa em outros lugares, você deve copiá-los também.

Programação defensiva é importante quando os objetos que você passam para um método é mutável.Uma boa prática (também descrita no livro Java efetivo) é torná-los imutáveis.

    .
  1. Se a aula de data não for final, você pode escrever uma aula de wrapper para ele, que é subclasse da data.
  2. depende.Provavelmente, não haverá necessidade de clonar.
  3. Não deveria incomodar você.O implementador de uma interface deve cuidar de problemas de sincronização.Geralmente, é uma boa prática passar interfaces em vez de suas implementações.
  4. Para coleções padrão Java há muitos métodos de utilidade na classe Java.util.collections, como UNModFiaBlelista e UNMdifiaBlemap, destinados a usar para programação defensiva.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top