1. Introdução a categorias imutáveis
Classe imutável: a chamada classe imutável significa que, uma vez que uma instância dessa classe é criada, seu valor variável de membro não pode ser alterado. Por exemplo, muitas classes imutáveis que acompanham JDK: interger, longa e corda, etc.
Classes variáveis: comparadas com classes imutáveis, as classes mutáveis podem alterar seus valores variáveis de membro após a criação de instâncias. A maioria das classes criadas em desenvolvimento pertence a classes mutáveis.
2 vantagens de classes imutáveis
Depois de falar sobre a diferença entre classes mutáveis e classes imutáveis, precisamos entender melhor por que existem classes imutáveis? Que benefícios esse recurso traz para Java?
1. Segurança da linha
Objetos imutáveis são seguros para roscas e podem ser compartilhados entre os threads. Não há necessidade de usar mecanismos especiais para garantir problemas de sincronização, porque o valor do objeto não pode ser alterado. Pode reduzir a possibilidade de erros simultâneos, porque não há necessidade de usar alguns mecanismos de bloqueio para garantir problemas de consistência da memória, o que também reduz a sobrecarga da sincronização.
2. Fácil de construir, usar e testar
3 ....
Método de design de classe imutável
Para o design de aulas imutáveis, resumo pessoalmente os seguintes princípios:
1. Adicione um modificador final à classe para garantir que a classe não seja herdada.
Se uma classe puder ser herdada, destruirá o mecanismo de imutabilidade da classe, desde que a classe de herança substitua os métodos da classe pai e a classe de herança puder alterar o valor da variável de membro, depois que a classe infantil aparecer como a classe pai, é possível garantir se a classe atual é mutável.
2. Verifique se todas as variáveis de membro devem ser privadas e a modificação final é adicionada
Dessa forma, garante que as variáveis de membros sejam imutáveis. Mas não basta fazer isso, porque se for uma variável de membro do objeto, é possível alterar seu valor externamente. Portanto, o quarto ponto compensa essa falha.
3. Nenhum método é fornecido para alterar as variáveis de membros, incluindo setters
Evite alterar o valor das variáveis de membros através de outras interfaces e destruir recursos imutáveis.
4. Inicialize todos os membros através do construtor e execute uma cópia profunda (cópia profunda)
Se o objeto passado pelo construtor for atribuído diretamente à variável do membro, ele ainda poderá ser alterado modificando o objeto de entrada, o que fará com que o valor da variável interna seja alterado. Por exemplo:
Classe final pública imutabledemo {private final int [] MyArray; public imutabledemo (int [] matriz) {this.myarray = array; // errado } }Este método não pode garantir a imutabilidade. MyArray e Array apontam para o mesmo endereço de memória. Os usuários podem alterar o valor dentro do MyArray modificando o valor do objeto Array fora do ImmutableDemo.
Para garantir que o valor interno não seja modificado, a cópia de profundidade pode ser usada para criar uma nova memória para salvar o valor recebido. Maneira correta de fazer isso:
Classe final pública Myimmutabledemo {private final int [] MyArray; public MyimmutableDemo (int [] Array) {this.myarray = array.clone (); }}5. No método getter, não retorne o próprio objeto diretamente, mas clone o objeto e retorne a cópia do objeto.
Essa abordagem também impede o vazamento de objetos e impede a operação direta das variáveis de membros após a obtenção de objetos de membros mutáveis internos por meio de getters, resultando em alterações nas variáveis de membros.
4. Imutabilidade de objetos de string
O objeto String não pode ser alterado após a criação da memória. A criação de objetos imutáveis geralmente atende aos 5 princípios acima. Vamos dar uma olhada em como o código da string é implementado.
Classe final da classe final Stringimplements java.io.Serializable, comparável <string>, Charsequence {/** O valor é usado para armazenamento de caracteres. */Valor final de char final privado [];/** O deslocamento é o primeiro índice do armazenamento usado. */private final Int Offset;/** A contagem é o número de caracteres na string. */private final int contagem;/** cache o código de hash para a string*/private int hash; // Padrão para 0..public String (Char Value []) {this.value = Arrays.copyof (value, value.length); // Operação de cópia profunda} ... public char [] toCharArray () {// não pode usar o Arrays.copyof por causa do resultado da ordem de inicialização da classe Result [] = new char [value.length]; system.arraycopy (valor, 0, resultado, 0, value.length); resultado de retorno;} ...}Conforme mostrado no código acima, os seguintes detalhes do design podem ser observados:
1. A classe de cordas é modificada por final e não pode ser herdada
2. Todos os membros da string são definidos como variáveis privadas
3. O Setter de Valor não existe
4. E definir valor e deslocar para Final.
5. Ao passar em um valor de matriz variável [], copie -o em vez de copiar o valor [] diretamente para a variável interna.
6. Ao obter o valor, ele não retorna diretamente a referência do objeto, mas retorna a cópia do objeto.
Isso é consistente com as características do tipo invariante resumido acima e também garante que o tipo de string seja uma classe imutável.
5. Vantagens e desvantagens da imutabilidade de objetos de string
A partir da análise da seção anterior, os dados da string são imutáveis; portanto, quais são os benefícios de definir esse recurso? Eu resumi o seguinte:
1. Requisitos para pools constantes de cordas.
Pools constantes de cordas podem reutilizar algumas constantes de caracteres no pool constante, evitando recriar o mesmo objeto todas as vezes e economizar espaço de armazenamento. Mas se a string for variável, a sequência do mesmo conteúdo também aponta para o mesmo espaço de memória do pool constante. Quando uma variável altera o valor dessa memória, os outros valores percorridos também serão alterados. Portanto, ele não está em conformidade com a intenção original do design constante do pool.
2. Considerações sobre segurança de threads.
A mesma instância da string pode ser compartilhada por vários threads. Dessa forma, não há necessidade de usar a sincronização devido a problemas de segurança de threads. As cordas são seguras de fios.
3. Os carregadores de classe precisam usar strings e a imutabilidade fornece segurança para que a classe correta seja carregada. Por exemplo, se você deseja carregar a classe Java.SQL.Connection e esse valor for alterado para MyHacked.Connection, isso causará danos desconhecidos ao seu banco de dados.
4. Suporte mapeamento de hash e cache.
Como as cordas são imutáveis, o código de hash é armazenado em cache quando é criado e não precisa ser recalculado. Isso torna as cordas muito adequadas como chaves no mapa, e a velocidade de processamento das strings é mais rápida que outros objetos -chave. É por isso que as chaves no hashmap costumam usar strings.
deficiência:
1. Se houver necessidade de alterar o valor do objeto String, um grande número de objetos de string será criado.
6. O objeto String é realmente imutável?
Embora o objeto String defina o valor para a final, ele também garante que suas variáveis de membro sejam imutáveis através de vários mecanismos. No entanto, ainda pode ser alterado através do mecanismo de reflexão. Por exemplo:
// Crie a string "Hello World" e atribua -a à referência sString s = "Hello World"; System.out.println ("s =" + s); // hello world // Obtenha o campo de valor no campo da classe String ValuefieldOfString = string.class.getDecaredfield ("value"); // altere a permissão de acesso do valor do atributo ValuefieldOfString.SetAccessible (true); '_'; System.out.println ("s =" + s); // hello_worldO resultado da impressão é:
s = olá mundos = hello_world
Verificou -se que o valor da string mudou. Ou seja, o chamado objeto "imutável" pode ser modificado através da reflexão.
Resumir
Uma classe imutável é o valor da travessia do membro que não pode ser alterada após a criação da instância. Esse recurso permite que classes imutáveis forneçam recursos seguros para roscas, mas também traz uma sobrecarga da criação de objetos. Cada mudança de atributo é recriar um novo objeto. O JDK também fornece muitas classes imutáveis, como inteiro, dupla, corda, etc. As características imutáveis da string são principalmente para atender às necessidades de constante agrupamento, segurança de threads e carregamento de classe. O uso racional de classes imutáveis pode trazer grandes benefícios.
O exposto acima é o mecanismo imutável do Java (imutável) e a imutabilidade da string (recomendada) introduzida a você pelo editor. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!