[RESOLVIDO] Classe Date - Ajuda

Boa noite pessoal, preciso da ajuda de vocês.
Preciso imprimir na tela a data de nascimento de uma pessoa e também calcular a idade.
Está retornando as informações erradas. Na parte da data de nascimento, ele não retorna no formato correto e quando calcula a idade, não consigo pegar somente o ano da data de nascimento informada:

package Pooexercicio01;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 *
 * @author migtr
 */
public class Pessoa {

    private String nome;
    private double altura;
    private Date dataNasc;

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public double getAltura() {
        return altura;
    }

    public void setAltura(double altura) {
        this.altura = altura;
    }

    public Date getDataNasc() {
        return dataNasc;
    }

    public void setDataNasc(Date dataNasc) {
        this.dataNasc = dataNasc;
    }

    public int calcularIdade() {

        Calendar c = Calendar.getInstance();
        int anoAtual = Calendar.YEAR;
        SimpleDateFormat formatador = new SimpleDateFormat("yyyy");
        int anoNasc = Integer.parseInt(formatador.format(this.getDataNasc()));

        return anoAtual - anoNasc;
    }

    public void imprimirDados() {
        System.out.println("NOME = " + this.getNome());
        System.out.println("ALTURA = " + this.getAltura());
        System.out.println("DATA DE NASCIMENTO = " + this.getDataNasc());
        System.out.println("IDADE = " + this.calcularIdade());
    }

e aqui segue o método main:

package Pooexercicio01;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;
import java.util.Date;

/**
 *
 * @author miguel
 *
 * Cria uma classe para representar uma Pessoa com os atributos privados de
 * nome, data de nascimento e altura. Crie os métodos públicos necessários para
 * getters e setters e também um método para imprimir todos dados de uma pessoa.
 * Crie um método para calcular a idade da pessoa.
 */
public class App {

    public static void main(String[] args) throws ParseException {
        
        Scanner sc = new Scanner(System.in);
        SimpleDateFormat formatador = new SimpleDateFormat("dd/MM/yyyy");
        
        String nome, dataString;
        double altura;
        Date dataNasc;
        
        System.out.print("Informe o nome: ");
        nome = sc.nextLine();
        
        System.out.print("Informe a altura: ");
        altura = Double.parseDouble(sc.nextLine());
        
        System.out.print("Informe a data de nascimento(dd/mm/aaaa): ");
        dataString = sc.nextLine();
        dataNasc = formatador.parse(dataString);
        
        Pessoa p = new Pessoa();
        p.setNome(nome);
        p.setAltura(altura);
        p.setDataNasc(dataNasc);
        
        System.out.println("");
        System.out.println("IDADE = " + p.calcularIdade());
        System.out.println("");
        p.imprimirDados();
public int calcularIdade() {
    Calendar c = Calendar.getInstance();
    int anoAtual = c.get(Calendar.YEAR);

    c.setTime(getDataNasc());

    int anoNasc = c.get(Calendar.YEAR);
    return anoAtual - anoNasc;
}
1 curtida

Não basta subtrair os anos, você também precisa verificar se já foi o aniversário da pessoa (se ainda não chegou, tem que subtrair 1):

public int calcularIdade() {
    Calendar c = Calendar.getInstance();
    int anoAtual = c.get(Calendar.YEAR);
    int mesAtual = c.get(Calendar.MONTH);
    int diaAtual = c.get(Calendar.DAY_OF_MONTH);

    c.setTime(this.dataNasc);
    int anoNasc = c.get(Calendar.YEAR);
    int mesNasc = c.get(Calendar.MONTH);
    int diaNasc = c.get(Calendar.DAY_OF_MONTH);

    int idade = anoAtual - anoNasc;
    // se ainda não chegou o aniversário, diminui 1
    if (mesAtual < mesNasc || (mesAtual == mesNasc && diaAtual < diaNasc))
        idade--;

    return idade;
}

A partir do Java 8

Qual versão do Java você está usando? Pois a partir do Java 8 existe uma API de datas muito melhor, o java.time.

No seu caso, como a data de nascimento só vai ter dia, mês e ano, pode-se usar um java.time.LocalDate no lugar de java.util.Date. E para converter de/para string, use um java.time.format.DateTimeFormatter.

Já para o cálculo da idade, basta usar um java.time.temporal.ChronoUnit, que cuida de todos os detalhes que citei acima. Ficaria assim:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoUnit;

public class Pessoa {
    public static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("dd/MM/uuuu").withResolverStyle(ResolverStyle.STRICT);

    private String nome;
    private double altura;
    private LocalDate dataNasc;
    // getters e setters, etc

    // criar construtor que já recebe todos os dados da pessoa
    public Pessoa(String nome, double altura, LocalDate dataNasc) {
        this.nome = nome;
        this.altura = altura;
        this.dataNasc = dataNasc;
    }

    public int calcularIdade() {
        return (int) ChronoUnit.YEARS.between(this.dataNasc, LocalDate.now());
    }

    public void imprimirDados() {
        // dentro da classe, não precisa necessariamente usar os getters, pode acessar os campos diretamente
        System.out.println("NOME = " + this.nome);
        System.out.println("ALTURA = " + this.altura);
        System.out.println("DATA DE NASCIMENTO = " + this.dataNasc.format(FMT));
        System.out.println("IDADE = " + this.calcularIdade());
    }
}

Outro detalhe é que criei um construtor que já recebe todos os dados da pessoa. Eu acho melhor assim do que criar a pessoa “vazia” e depois chamar os setters um a um. Afinal, faz sentido ter uma pessoa sem nome, altura e data de nascimento? Pois é isso que new Pessoa() faz. Eu acho que faz mais sentido criar a pessoa já com todos os dados - claro que aí depende do contexto, mas de forma geral só crie construtores que façam sentido.

Enfim, no main ficaria algo assim:

public static void main(String args[]) throws Exception {
    Scanner sc = new Scanner(System.in);
    System.out.print("Informe o nome: ");
    String nome = sc.nextLine();
    System.out.print("Informe a altura: ");
    double altura = Double.parseDouble(sc.nextLine());
    System.out.print("Informe a data de nascimento(dd/mm/aaaa): ");
    LocalDate dataNasc = LocalDate.parse(sc.nextLine(), Pessoa.FMT);

    Pessoa p = new Pessoa(nome, altura, dataNasc);
    p.imprimirDados();
}

@staroski, muito obrigado!
@hugokotsubo muito obrigado pela explicação, vou dar uma olhada nessa API, estou fazendo um curso, mas não explicaram como funciona esse Date, aí fiquei todo enrolado, já que estou bem no início do aprendizado. Muito obrigado!!!