我的程序“日期”中的未知NullPointerException

时间:2015-10-06 11:42:21

标签: java date nullpointerexception

好吧,我一直在练习Java,过了一段时间我决定创建一个与Dates一起运行的程序。我的问题是,当我对我的班级进行测试时,我得到一个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)的切换案例中退出,但我一直试图改变它,没有任何反应。

编辑:是的,你是对的!错误就像在构造函数方法中更改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 个答案:

答案 0 :(得分:1)

您尚未设置mes属性设置器中使用的dia属性

答案 1 :(得分:0)

更改构造函数中setter的顺序:

        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]));
        }

您必须先设置月份,因为您在设置日内使用它。

答案 2 :(得分:0)

你取决于已经设定的东西。

  • setDia调用getMes()

  • setDia还调用esBisiesto()调用getAnnio()

但Annio和Mes都没有初始化。

一种简单的方法是修改构造函数:

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