final e outras palavras-chave Java - 1

"Olá, amigo!"

"Oi, Bilaabo!"

"Hoje vou falar sobre várias palavras-chave em Java. Mas vou começar com a mais interessante: a palavra-chave final. "

"Você pode usar a palavra-chave final ao declarar uma variável, método ou classe."

"E por que precisamos de final?"

"É bem simples. Se marcarmos uma variável como final, ela se tornará imutável:"

final int i = 5;
i++; //Compilation error: the value of i cannot be changed.

"Eu vejo."

"Se marcarmos um método como final, a substituição do método em classes derivadas é proibida:"

class Cat
{
 public final String getName()
 {
  return "cat";
 }
}

class Tiger extends Cat
{
 public String getName() //Compilation error: overriding the getName()
 {
  return "tiger";
 }
}

"Entendo. Mas por que você precisaria proibir a substituição de um método?"

"Bem, como exemplo, suponha que um programador tenha escrito muitos códigos importantes em um método e queira garantir que todas as classes que herdam sua classe tenham o comportamento especificado."

"E, finalmente, o terceiro uso."

"Se marcarmos uma classe com a palavra-chave final, ela não poderá ser herdada."

public final class Cat
{
 public String getName()
 {
  return "cat";
 }
}

class Tiger extends Cat //Compilation error: the Cat class cannot be
{
 public String getName()
 {
  return "tiger";
 }
}

"E por que impediríamos que uma classe fosse herdada?"

"Você deve entender que não evitamos que a herança seja irritante, mas sim por uma questão de segurança e integridade do código. Se a herança de classe não for proibida, a implicação é que ela é permitida. E que o código escrito pelos designer funcionará corretamente para objetos desta classe, bem como objetos de quaisquer classes derivadas."

"Mas se um desenvolvedor perceber que mesmo pequenas mudanças em sua classe farão com que tudo pare de funcionar como esperado, então é melhor proibir a herança."

"Por exemplo, a classe String é declarada como final, assim como todos os tipos primitivos: Integer, Boolean, Double, Character…"

"Ah, entendi. A classe String foi criada como uma classe imutável e se eles fossem mutáveis ​​de repente, muitas coisas parariam de funcionar."

"Bem, quase. Vamos colocar desta forma: tudo funcionaria quase como antes, mas às vezes haveria erros que seriam muito difíceis de encontrar e entender. Então, em alguns casos, herdar classes ou métodos não é realmente um pecado, mas proibir isso significa menos erros para detectar mais tarde."

"Onde mais você pode usar final?"

"Você pode usar final antes de parâmetros de função e antes de variáveis ​​em um método. Aqui está um exemplo:"

public void setName(final String name)
{
 final String displayName = "Mr."+ name;
  …
 this.name = displayName;
}

"E qual é o sentido disso?"

"Bem, existem dois. Primeiro, declaramos uma variável como final se quisermos dizer a outros desenvolvedores que esse valor é uma constante específica e não apenas uma variável."

Por exemplo, queremos calcular o imposto sobre vendas com base em um preço:

public int getPriceNDS()
{
 final int NDS = 20;
 return this.price * NDS / 200;
}

"E segundo, precisamos desse tipo de variável ao escrever classes internas locais ou anônimas. Falarei sobre esses tipos de classes em breve. Mas não hoje."

"Ok, até agora não houve nada muito complicado."

"Observe que apenas a variável se torna imutável, não um objeto ao qual ela possa se referir. O objeto ainda pode ser alterado."

"Na verdade, eu estava prestes a perguntar sobre isso. E não há como tornar o objeto imutável?"

"Não, a menos que você escreva uma classe imutável."

"Observe que, como o valor de uma variável final não pode ser alterado, você deve atribuir seu valor inicial imediatamente."

Este código irá compilar Este código não compila
class Home
{
 private final int width = 200;
 private final int height = 100;

 public Home()
 {
 }
}
class Home
{
 private final int width;
 private final int height;

 public Home()
 {
 }
}

"Mas, dito isso, Java permite atrasar a inicialização das variáveis ​​finais de uma classe até o construtor."

Este código irá compilar Este código não compila
class Home
{
 private final int width = 200;
 private final int height;

 public Home()
 {
  height = 100;
 }
}
class Home
{
 private final int width;
 private final int height;

 public Home()
 {
  height = 100;
 }
}

"Além disso, diferentes construtores podem inicializar variáveis ​​finais com valores diferentes. Isso é bastante conveniente:"

Este código irá compilar
class Home
{
 private final int width;
 private final int height;

 public Home()
 {
  height = 100;
  width = 200;
 }

 public Home(int width)
 {
  this.height = 300;
  this.width = width;
 }

 public Home(int width, int height)
 {
  this.height = height;
  this.width = width;
 }
}

"Esse foi um tema muito interessante, e absolutamente tudo faz sentido. Obrigado, Bilaabo!"