Reputation: 107
Well, I've been keeping practicing Java and after a while I decided to create a program that operates with Dates. My problem is that when I did a test of my class, I get a NullPointerException
and I don't know where the error is. Here's my interface:
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();
}
Here's the class:
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;
}
}
And here's the test (main):
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);
}
}
I suspect that the problem exits in the switch case from method setDia() (lane 39)
, but I've been trying to change it and nothing happens.
EDIT: Yes you were right guys! The error was so simple as changing the setters in my constructor method. Here's the fixed class if you want to use it. Thank you a lot!
//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;
}
Upvotes: 0
Views: 66
Reputation: 7057
You are depending on things already being set.
setDia calls getMes()
setDia also calls esBisiesto() which calls getAnnio()
But both Annio and Mes are not initialized yet.
An easy way to fix it is to reorder the constructor:
setAnnio(a);
setMes(m);
setDia(d);
Upvotes: 0
Reputation: 11620
Change order of setters in your constructor:
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]));
}
You must set month first, because you are using it inside setting day.
Upvotes: 0
Reputation: 361
You haven't set your mes
attribute which is used in setter of dia
attribute
Upvotes: 1