Criar um atributo que não pode ser modificado em java

Eu estou iniciando em orientação a objetos em java e minha duvida é a seguinte:
eu tenho 3 classes, a classe Human:

public class Human {
//Atributos não importantes agora......
	private Date nascimento = new Date(1,1,1);

//+metodos não importantes agora.....
	public Date nascimento() {
		return this.nascimento;
	}
	//builders
	Human(String nome, int diaNacimeto, int mesNacimento, int anoNacimento){
		setNome(nome);
	}}

A classe Date

public class Date {
	private int dia = 0;
	private int mes = 0;
	private int ano = 0;
	
	public int getDia(){
		return(this.dia);
	}
	public int getMes(){
		return(this.mes);
	}
	public int getAno(){
		return(this.ano);
	}
	String getData() {
		return(this.dia+"/"+this.mes+"/"+this.ano);
	}
	
	public void setDia(int novoDia) {//funcionamento interno não importante.....}
	public void setMes(int novoMes) {//funcionamento interno não importante.....}
	public void setAno(int novoAno) {
		this.ano = novoAno;
	}
	public void setData(int novoDia, int novoMes, int novoAno) {
		setAno(novoAno);
		setMes(novoMes);
		setDia(novoDia);
	}
	
	Date(int novoDia, int novoMes, int novoAno){
		setAno(novoAno);
		setMes(novoMes);
		setDia(novoDia);
		
		
	}
	
}

E finalmente o Main:

public class Main {
	public static void main(String[] args) {
		Human kawan = new Human("kawan", 31, 07, 2009);
		kawan.nascimento().setData(03, 07, 2003);
		System.out.println(kawan.nascimento().getData());
	}
}

Repare que no Main eu tenho kawan.nascimento().getData() a pergunta é, a alguma forma de fazer esse pedaço de código mais “bonito”?
Eu gostaria de acessar o atributo nascimento diretamente sem usar um método mas ainda sem que essa possa ser alterada.
A alguma forma de acessar atributos sem que se possa editalo? De formar que se eu tentasse System.out.print(kawan.nascimento) daria certo, mas se eu tentasse kawan.nascimento = new Date() desse errado.

Marca o atributo como final mas isso vai te obrigar a inicializá-lo no construtor.
Fazendo isso, nem precisa do getter e setter, pode deixar ele como public.

Isso é até comum, por exemplo o atributo out da classe System e o atributo length de qualquer array.

Você tem acesso ao atributo sem getter e setter, mas se tentar fazer algo confirme abaixo, terá erro de compilação:

System.out = outroPrintStream; // erro de compilação

int[] array = new int[10];
array.length = outroTamanho; // erro de compilação
1 curtida