Oi Anderson, tudo bem?
Esta observação sempre rende muita conversa kkkkk
Bom vou tentar dar algumas razões pelas quais é bom evitar o uso generalizado de atributos públicos, mesmo se forem final
:
Fere o conceito de encapsulamento pois você está expondo atributos daquela classe. O ideal é que o código que usa deve conhecer a interface de uso e não detalhes internos da classe como atributos;
Por conhecer detalhes internos, o código que usa fica com alto acoplamento com a classe que expôs os atributos. Qualquer mudança que você queira fazer na forma que este dado for obtido, pode quebrar o seu código muito facilmente. Se você tiver um getter ou um método de acesso, você pode mudar a implementação que o código de fora não vai quebrar; -- Já parou pra pensar se eles resolvessem mudar o System.out
o caos que seria?
Se você for usar este atributo com frameworks que usam a convenção de Java Beans, é necessário que você tenha um getter senão não consegue usar as facilidades fornecidas;
Um atributo final
pode sempre gerar mais trabalho para você verificar se ele é realmente imutável. Você pode estar se perguntando "Se eu coloco final ele já não é imutável? ". Aí é que está pode existir uma confusão aqui. Por exemplo, imagine o seguinte código:
public class Pagamento {
public final Calendar dataPgto;
// outros atributos...
public Pagamento(Calendar dataPgto) {
this.dataPgto = dataPgto;
}
// métodos
}
Aí na hora de usar você faz o seguinte:
public class PagaFuncionario {
public static void main(String []args) {
Calendar dataAtual = new GregorianCalendar(2019, Calendar.MARCH, 31);
Pagamento pgtoMarco = new Pagamento(dataAtual);
// ...
}
}
Parece de boas mas você pode fazer:
public class PagaFuncionario {
public static void main(String []args) {
Calendar dataAtual = new GregorianCalendar(2019, Calendar.MARCH, 31);
Pagamento pgtoMarco = new Pagamento(dataAtual);
pgtoMarco.dataPgto = new GregorianCalendar(2019, Calendar.MARCH, 29); // Putz isso aqui não dá! Bacana!
pgtoMarco.dataPgto.add(-2, Calendar.DAY_OF_MONTH); //Isso funciona!
}
}
Outra coisa que também funciona:
public class PagaFuncionario {
public static void main(String []args) {
Calendar dataAtual = new GregorianCalendar(2019, Calendar.MARCH, 31);
Pagamento pgtoMarco = new Pagamento(dataAtual);
dataAtual.add(-2, Calendar.DAY_OF_MONTH); // Vai mudar a data do Pagamento.dataPgto também
}
}
Isto acontece porque o que é imutável é o valor daquele atributo. Se você tem um atributo que é do tipo referência, ou seja, guarda uma referência para um objeto, você precisa verificar se ele é realmente imutável. No caso acima, podemos ver que a classe Calendar
não é, por isso e por outras coisas hoje temos a classe LocalDate
que é realmente imutável. Desta forma ao olhar um atributo public
e final
é possível que você precise verificar se a imutabilidade foi realmente implementada, devolvendo cópias daquele objeto ou não, o que gera muito mais trabalho.
Estas são algumas razões pelas quais é bom evitar, se ficou mais alguma dúvida ou se não concordar é só falar!
Abraço!