有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

我的程序“Date”中的java未知NullPointerException

嗯,我一直在练习Java,过了一段时间我决定创建一个带有日期的程序。我的问题是,当我对我的类进行测试时,我得到一个NullPointerException,我不知道错误在哪里。这是我的界面:

package fecha;

public interface Fecha extends Cloneable, Copiable<Fecha>, Comparable<Fecha> {

    Integer getDia();
    Integer getMes();
    Integer getAnnio();
    void setDia(Integer dia);
    void setMes(Integer mes);
    void setAnnio(Integer annio);
    Boolean esBisiesto();
    void fechaAnterior();
    void fechaSiguiente();
}

下面是课程:

package fecha;

import java.util.Objects;

public class FechaImpl implements Fecha{

    //Atributos

    private Integer dia;
    private Integer mes;
    private Integer annio;

    //Métodos get/set

    public Integer getDia(){

        return dia;
    }

    public Integer getMes(){

        return mes;
    }

    public Integer getAnnio(){

        return annio;
    }

    public void setDia(Integer d){

        if(d < 1 || d > 31){

            throw new IllegalArgumentException("Dia no valido");
        }

        Integer numeroDias = 30;

        switch(getMes() ){

            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                numeroDias = 31;
                break;
            case 2:
                numeroDias = esBisiesto() ? 29 : 28;
                break;
        }

        if (d > numeroDias) throw new IllegalArgumentException("Dia no valido");

        this.dia = d;
    }

    public void setMes(Integer m){

        if(m < 1 || m > 12){

            throw new IllegalArgumentException("Mes no valido");
        }

        this.mes = m;
    }

    public void setAnnio(Integer a){

        if(a < 1900){

            throw new IllegalArgumentException("Annio no valido");
        }

        this.annio = a;
    }
    //Métodos constructores

    public FechaImpl(Integer d, Integer m, Integer a){

        setDia(d);
        setMes(m);
        setAnnio(a);
    }

    public FechaImpl(String fecha){

        String[] dato = fecha.split("/");

        setDia(Integer.parseInt(dato[0]));
        setMes(Integer.parseInt(dato[1]));
        setAnnio(Integer.parseInt(dato[2]));
    }

    //Otros métodos

    public Boolean esBisiesto(){

        Boolean res;
        res = ((getAnnio() % 4 == 0) && ((getAnnio() % 100 != 0) || (getAnnio() % 400 == 0))) ? true : false;

        return res;
    }

    public void fechaAnterior(){
        if(getDia().compareTo(1) == 0){
            setDia(30);
            if(getMes().compareTo(1) == 0){
                setMes(12);
                setAnnio(getAnnio() - 1);
            }else {
                setMes(getMes() - 1);
            }
        }else {
            setDia(getDia() - 1);
        }   
    }

    public void fechaSiguiente(){
        if(getDia().compareTo(30) == 0){
            setDia(1);
            if(getMes().compareTo(12) == 0){
                setMes(1);
                setAnnio(getAnnio() + 1);
            }else {
                setMes(getMes() + 1);
            }
        }else {
            setDia(getDia() + 1);
        }

    }

    //Comparable

    public int compareTo(Fecha o){

        int res = getAnnio().compareTo(o.getAnnio());
        if(res == 0){
                res = getMes().compareTo(o.getMes());
                if(res == 0){
                    res = getDia().compareTo(o.getDia());
                }
        }
        return res;
    }

    //Equals/hashcode

    @Override

    public boolean equals(Object o){

        boolean res = false;
        if(o instanceof Fecha){

            Fecha f = (Fecha) o;
            res = getDia().equals(f.getDia()) && getMes().equals(f.getMes()) && getAnnio().equals(f.getAnnio());
        }
        return res;
    }

    @Override

    public int hashCode(){

        return Objects.hash(this.getDia(), this.getMes(), this.getAnnio());
    }

    //A cadena

    @Override

    public String toString(){

        String s = "[" + getDia() + "," + getMes() + "," + getAnnio() + "]";
        return s;
    }

    //Cloneable

    @Override

    public Fecha clone(){

        Fecha copia = null;
        try{
            copia = (Fecha) super.clone();
        } catch (CloneNotSupportedException e){

            e.printStackTrace();
        }

        return copia;
    }
}

以下是测试(主要测试):

package fecha;

public class Main {

    public static void main(String[] args) {

        FechaImpl prueba = new FechaImpl ("20/10/1995");
        FechaImpl test = new FechaImpl (20, 10, 1995);

        System.out.println(prueba);
        System.out.println(test);

    }

}

我怀疑在方法setDia() (lane 39)的switch案例中存在问题,但我一直在尝试更改它,但什么也没有发生

编辑:是的,你们是对的!这个错误非常简单,只需在构造函数方法中更改setter即可。这是固定类,如果你想使用它。多谢各位

//Atributos

private Integer dia;
private Integer mes;
private Integer annio;

//Métodos get/set

public Integer getDia(){

    return dia;
}

public Integer getMes(){

    return mes;
}

public Integer getAnnio(){

    return annio;
}

public void setDia(Integer d){

    if(d < 1 || d > 31){

        throw new IllegalArgumentException("Dia no valido");
    }

    Integer numeroDias = 30;

    switch(getMes() ){

        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            numeroDias = 31;
            break;
        case 2:
            numeroDias = esBisiesto() ? 29 : 28;
            break;
    }

    if (d > numeroDias) throw new IllegalArgumentException("Dia no valido");

    this.dia = d;
}

public void setMes(Integer m){

    if(m < 1 || m > 12){

        throw new IllegalArgumentException("Mes no valido");
    }

    this.mes = m;
}

public void setAnnio(Integer a){

    if(a < 1900){

        throw new IllegalArgumentException("Annio no valido");
    }

    this.annio = a;
}
//Métodos constructores

public FechaImpl(Integer d, Integer m, Integer a){

    setAnnio(a);
    setMes(m);
    setDia(d);
}

public FechaImpl(String fecha){

    String[] dato = fecha.split("/");

    setAnnio(Integer.parseInt(dato[2]));
    setMes(Integer.parseInt(dato[1]));
    setDia(Integer.parseInt(dato[0]));
}

//Otros métodos

public Boolean esBisiesto(){

    Boolean res;
    res = ((getAnnio() % 4 == 0) && ((getAnnio() % 100 != 0) || (getAnnio() % 400 == 0))) ? true : false;

    return res;
}

public void fechaAnterior(){
    if(getDia().compareTo(1) == 0){
        setDia(30);
        if(getMes().compareTo(1) == 0){
            setMes(12);
            setAnnio(getAnnio() - 1);
        }else {
            setMes(getMes() - 1);
        }
    }else {
        setDia(getDia() - 1);
    }   
}

public void fechaSiguiente(){
    if(getDia().compareTo(30) == 0){
        setDia(1);
        if(getMes().compareTo(12) == 0){
            setMes(1);
            setAnnio(getAnnio() + 1);
        }else {
            setMes(getMes() + 1);
        }
    }else {
        setDia(getDia() + 1);
    }

}

//Comparable

public int compareTo(Fecha o){

    int res = getAnnio().compareTo(o.getAnnio());
    if(res == 0){
            res = getMes().compareTo(o.getMes());
            if(res == 0){
                res = getDia().compareTo(o.getDia());
            }
    }
    return res;
}

//Equals/hashcode

@Override

public boolean equals(Object o){

    boolean res = false;
    if(o instanceof Fecha){

        Fecha f = (Fecha) o;
        res = getDia().equals(f.getDia()) && getMes().equals(f.getMes()) && getAnnio().equals(f.getAnnio());
    }
    return res;
}

@Override

public int hashCode(){

    return Objects.hash(this.getDia(), this.getMes(), this.getAnnio());
}

//A cadena

@Override

public String toString(){

    String s = "[" + getDia() + "," + getMes() + "," + getAnnio() + "]";
    return s;
}

//Cloneable

@Override

public Fecha clone(){

    Fecha copia = null;
    try{
        copia = (Fecha) super.clone();
    } catch (CloneNotSupportedException e){

        e.printStackTrace();
    }

    return copia;
}

共 (3) 个答案

  1. # 1 楼答案

    你取决于已经设置好的东西

    • setDia调用getMes()

    • setDia还调用esBisiesto(),后者调用getAnnio()

    但是Annio和Mes都还没有初始化

    修复它的一个简单方法是重新排序构造函数:

        setAnnio(a);
        setMes(m);
        setDia(d);
    
  2. # 2 楼答案

    您尚未设置mes属性,该属性在dia属性的setter中使用

  3. # 3 楼答案

    构造函数中设置器的更改顺序:

            public FechaImpl(Integer d, Integer m, Integer a){
                setMes(m);
                setDia(d);
                setAnnio(a);
            }
    
            public FechaImpl(String fecha){
    
                String[] dato = fecha.split("/");
    
                setMes(Integer.parseInt(dato[1]));
                setDia(Integer.parseInt(dato[0]));
                setAnnio(Integer.parseInt(dato[2]));
            }
    

    你必须先设定月份,因为你是在设定日期内使用它