JavaRush /Blogue Java /Random-PT /Pausa para café #134. O que evitar ao escrever código Jav...

Pausa para café #134. O que evitar ao escrever código Java. Como final, finalmente e finalize são usados em Java

Publicado no grupo Random-PT

O que evitar ao escrever código Java

Fonte: Médio Chamamos sua atenção para um artigo que lista erros comuns que os desenvolvedores cometem ao escrever código Java. Pausa para café #134.  O que evitar ao escrever código Java.  Como final, finalmente e finalize são usados ​​em Java - 1

Usando Enum.values

O fato de isso ter sido considerado um bug me pegou de surpresa, já que eu usava Enum.values ​​regularmente . O problema aqui é que Enum.values() deveria ser uma lista imutável por especificação. Para fazer isso, ele deve retornar uma nova instância do array com os valores enum cada vez que for chamado.
public enum Fruits {
    APPLE, PEAR, ORANGE, BANANA;

    public static void main(String[] args) {
        System.out.println(Fruits.values());
        System.out.println(Fruits.values());
    }
}
// output
// [Lcom.test.Fruits;@7ad041f3
// [Lcom.test.Fruits;@251a69d7
Existem dois objetos separados na memória aqui, então pode não parecer grande coisa. Mas se você usar Fruit.values() ao processar uma solicitação e tiver uma carga alta, isso pode levar a problemas de memória. Você pode corrigir isso facilmente introduzindo uma variável final estática privada VALUES para armazenamento em cache.

Passando parâmetros opcionais como parâmetro de método

Considere o seguinte código:
LocalDateTime getCurrentTime(Optional<ZoneId> zoneId) {
    return zoneId.stream()
        .map(LocalDateTime::now)
        .findFirst()
        .orElse(LocalDateTime.now(ZoneId.systemDefault()));
}
Passamos o parâmetro opcional zoneId e, com base em sua presença, decidimos se devemos fornecer a hora no fuso horário do sistema ou usar o fuso horário especificado. No entanto, esta não é a maneira correta de trabalhar com Opcional. Devemos evitar usá-los como parâmetro e, em vez disso, usar a sobrecarga de métodos.
LocalDateTime getCurrentTime(ZoneId zoneId) {
  return LocalDateTime.now(zoneId);
}

LocalDateTime getCurrentTime() {
  return getCurrentTime(ZoneId.systemDefault());
}
O código que você vê acima é muito mais fácil de ler e depurar.

Usando StringBuilder

Strings em Java são imutáveis. Isso significa que, uma vez criados, eles não serão mais editáveis. A JVM mantém um pool de strings e, antes de criar um novo, chama o método String.intern() , que retorna uma instância do pool de strings correspondente ao valor, se existir. Digamos que queremos criar uma string longa concatenando elementos nela.
String longString = new StringBuilder()
  .append("start")
  .append("middle")
  .append("middle")
  .append("middle")
  .append("end")
  .toString();
Recentemente, fomos informados de que esta era uma péssima ideia porque as versões mais antigas do Java faziam o seguinte:
  • na linha 1 a string “start” é inserida no conjunto de strings e apontada por longString
  • a linha 2 adiciona a string “startmiddle” ao pool e aponta para ela com longString
  • na linha 3 temos “startmiddlemiddle”
  • na linha 4 - “startmiddlemiddlemiddle”
  • e finalmente na linha 5 adicionamos “startmiddlemiddlemiddleend” ao pool e apontamos longString para ele
Todas essas linhas permanecem no pool e nunca são usadas, resultando no desperdício de uma grande quantidade de RAM. Para evitar isso podemos usar StringBuilder.
String longString = new StringBuilder()
  .append("start")
  .append("middle")
  .append("middle")
  .append("middle")
  .append("end")
  .toString();
StringBuilder cria apenas uma string quando o método toString é chamado , livrando-se assim de todas as strings intermediárias que foram inicialmente adicionadas ao pool. Porém, após o Java 5 isso é feito automaticamente pelo compilador , então é melhor usar a concatenação de strings usando “+”.

Usando wrappers primitivos quando não são necessários

Considere os dois fragmentos a seguir:
int sum = 0;
for (int i = 0; i < 1000 * 1000; i++) {
  sum += i;
}
System.out.println(sum);
Integer sum = 0;
for (int i = 0; i < 1000 * 1000; i++) {
  sum += i;
}
System.out.println(sum);
O primeiro exemplo é executado seis vezes mais rápido que o segundo no meu computador. A única diferença é que usamos uma classe wrapper Integer. A forma como Integer funciona é que na linha 3, o tempo de execução deve converter a variável sum em um inteiro primitivo (unboxing automático) e, após a adição ser feita, o resultado é então agrupado em uma nova classe Integer. (embalagem automática). Isso significa que estamos criando 1 milhão de classes inteiras e realizando dois milhões de operações de empacotamento, o que explica a dramática desaceleração. As classes wrapper só devem ser usadas quando precisam ser armazenadas em coleções. No entanto, versões futuras do Java suportarão coleções de tipos primitivos, o que tornará os wrappers obsoletos.

Como final, finalmente e finalize são usados ​​em Java

Fonte: Newsshare Neste artigo você aprenderá onde, quando e por que a palavra-chave Finalize é usada e se vale a pena usá-la em Java. Você também aprenderá as diferenças entre final, finalmente e finalizar.

Onde um bloco final é usado?

O bloco final em Java é usado para abrigar partes importantes do código, como código de limpeza, fechamento de um arquivo ou fechamento de uma conexão, por exemplo. O bloco final é executado independentemente de uma exceção ser lançada ou tratada. A finalmente contém todas as declarações importantes, independentemente de ocorrer uma exceção ou não.

Como você finaliza uma variável em Java?

Existem 3 maneiras de inicializar uma variável Java final:
  • Você pode inicializar uma variável final quando ela for declarada. Essa abordagem é a mais comum.
  • Uma variável final vazia é inicializada em um bloco ou construtor inicializador de instância.
  • Uma variável estática final vazia é inicializada dentro de um bloco estático.

Podemos chamar o método finalize manualmente em Java?

O método finalize() não é necessário e não é recomendado ser chamado quando um objeto sai do escopo. Porque não se sabe antecipadamente quando (ou se) o método finalize() será executado . Em geral, finalizar não é o melhor método a ser usado, a menos que haja uma necessidade específica. A partir do Java 9 ele está obsoleto.

Quando o método finalize é chamado?

O método finalize() é chamado para realizar a limpeza antes da coleta de lixo.

Qual é a diferença entre final, finalmente e finalizar?

A principal diferença entre final, finalmente e finalize é que final é um modificador de acesso, finalmente é um bloco no tratamento de exceções e finalize é um método de uma classe de objeto.

É possível substituir métodos finais?

Não, os métodos declarados como finais não podem ser substituídos ou ocultados.

Podemos usar try sem catch?

Sim, é possível ter um bloco try sem um bloco catch usando um bloco final . Como sabemos, o bloco final sempre será executado mesmo que ocorra alguma exceção diferente de System no bloco try.

Quais são os métodos finais?

Os métodos finais não podem ser substituídos ou ocultados por subclasses. Eles são usados ​​para evitar comportamento inesperado de uma subclasse modificando um método que pode ser crítico para a função ou consistência da classe.

Um construtor pode ser final?

Os construtores NUNCA podem ser declarados finais. Seu compilador sempre gerará um erro como “modificador final não permitido”. Final, quando aplicado a métodos, significa que o método não pode ser substituído em uma subclasse. Construtores NÃO são métodos regulares.

Para que é usada a palavra-chave finalmente?

A palavra-chave finalmente é usada para criar um bloco de código após um bloco try. O bloco final é sempre executado independentemente de ocorrer uma exceção. Usar um bloco final permite executar qualquer instrução do tipo desenrolamento que você deseja executar, independentemente do que está acontecendo no código protegido.

Qual é a utilidade de finalmente?

Um bloco final em Java é um bloco usado para executar partes do código, como fechar uma conexão e outros. O bloco final em Java é sempre executado, independentemente de a exceção ser tratada ou não. Portanto, ele contém todas as instruções necessárias que precisam ser impressas, independentemente de ocorrer uma exceção ou não.

Por que o método Finalize está protegido?

Por que o modificador de acesso do método finalize() está protegido? Por que não pode ser público? Não é público porque não deve ser chamado por ninguém além da JVM. Entretanto, ele deve ser protegido para que possa ser substituído por subclasses que precisam definir seu comportamento.

O método finalize é sempre chamado em Java?

O método finalize é chamado quando um objeto está prestes a ser coletado como lixo. Isso pode acontecer a qualquer momento depois que ele se tornar elegível para coleta de lixo. Observe que é perfeitamente possível que o objeto nunca seja coletado como lixo (e, portanto, finalize nunca seja chamado).

Qual é a diferença entre arremessar e arremessar?

A palavra-chave throw é usada para lançar uma exceção intencionalmente. A palavra-chave throws é usada para declarar uma ou mais exceções, separadas por vírgulas. Ao usar throw, apenas uma exceção é lançada.

Qual é a diferença entre palavras-chave try catch e finalmente?

Estes são dois conceitos diferentes: um bloco catch é executado somente se ocorrer uma exceção no bloco try. O bloco final é sempre executado após o bloco try(-catch), independentemente de uma exceção ter sido lançada ou não.

Podemos usar finalmente sem tentar em Java?

Um bloco finalmente deve estar associado a um bloco try; você não pode usar finalmente sem um bloco try. Você deve colocar neste bloco aquelas instruções que sempre devem ser executadas.

Podemos herdar o método final?

O método final é herdado? Sim, o método final é herdado, mas você não pode substituí-lo.

Qual método não pode ser substituído?

Não podemos substituir métodos estáticos porque a substituição de métodos é baseada em links dinâmicos em tempo de execução e métodos estáticos são vinculados usando links estáticos em tempo de compilação. Portanto, a substituição de métodos estáticos não é possível.

O que acontece se o método final for substituído?

Um método final declarado em uma classe pai não pode ser substituído por uma classe filha. Se tentarmos substituir o último método, o compilador lançará uma exceção em tempo de compilação.

A palavra-chave final e o método finalize funcionam da mesma forma?

Não há semelhanças em suas funções, exceto nomes semelhantes. A palavra-chave final pode ser usada com uma classe, método ou variável em Java. Uma classe final não é extensível em Java, um método final não pode ser substituído e uma variável final não pode ser modificada.

Qual é a super palavra-chave em Java?

A palavra-chave super em Java é uma variável de referência usada para se referir ao objeto imediato da classe pai. Sempre que você instancia uma subclasse, uma instância da classe pai é criada em paralelo, que é referenciada pela variável de referência super. A palavra-chave super pode ser usada para chamar diretamente um método de uma classe pai.

Qual é a diferença entre as palavras-chave estáticas e finais?

A principal diferença entre as palavras-chave estáticas e finais é que a palavra-chave estática é usada para definir um membro de uma classe que pode ser usado independentemente de qualquer objeto dessa classe. A palavra-chave Final é usada para declarar uma variável constante, um método que não pode ser substituído e uma classe que não pode ser herdada.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION