Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy constructor isn't working

iv'e just started learning about copy constructors in java (OOP). but for some reason it doesn't work for me. this is what I did : class Date:

public class Date {
private int day;
private int month;
private int year;
//regular build function
public Date(int day,int month, int year)
{
  this.day=day;
  this.month=month;
  this.year=year;
}    
//copy constructor
public Date (Date date){
    this.day = date.day;
    this.year = date.year;
    this.month = date.month;
}   
public String toString()
{
  return this.day+"/"+this.month+"/"+this.year;
}
}

the class Passport :

 public class Passport {
private String name; //the name property
private int number; //the number property
private Date expiryDate; //the expiryDate property
//a regular building constructor
public Passport(String name,int number, Date expiryDate)
{
  this.name=name;
  this.number=number;
  Date copyExpiryDate = new Date(this.expiryDate);  
  this.expiryDate = copyExpiryDate;
} 
//a copy constructor
public Passport(Passport passport)
{
  this.name = passport.name;
  this.number = passport.number;
  this.expiryDate = passport.expiryDate;
}   

the main method is :

 import java.util.*;
 public class Check {
static Scanner reader=new Scanner(System.in);
//checking if the classes are working properly
public static void main(String[] args){
    int numtraveler,passNum,passDay,passMonth,passYear,pay,planDay,planMonth,planYear;
    String name; 
    boolean isPay=false;
    System.out.println("how many travelers are you?");
    numtraveler=reader.nextInt();
    for(int i=0 ; i<numtraveler ; i++){
        System.out.println("enter your passport : ");
        System.out.println("enter name : ");
        name=reader.next();
        System.out.println("enter passport number : ");
        passNum=reader.nextInt();
        System.out.println("enter your passport's expiry date : (day then month then year) ");
        passDay=reader.nextInt();
        passMonth=reader.nextInt();
        passYear=reader.nextInt();
        Date d1=new Date(passDay,passMonth,passYear);
        System.out.println(d1);
        Passport p1=new Passport(name,passNum,d1);
        System.out.println(p1);
        Traveler t1=new Traveler(p1,isPay);
        System.out.println("do you want to pay? :(enter o if yes and 1 if not) ");
        pay=reader.nextInt();
        if(pay==0){
            t1.pay();
        }
        System.out.println("when are you planning to travel?(enter day then month then year)");
        planDay=reader.nextInt();
        planMonth=reader.nextInt();
        planYear=reader.nextInt();
        Date dPlan=new Date(planDay,planMonth,planYear);
        if(t1.checkTravel(dPlan)){
            System.out.println("The travel is possible");
        }
        else
            System.out.println("The travel isn't possible");            
    }
}
}

I have omitted some unimportant information from the class- the get and set from date, some other functions they both had and another class called Traveler because They aren't that relevant to the problem. The Traveler class uses the Passport copy constructor but it has the same problem there. When I run the main method it gets to the date,creates the object d1 and displays the date but when it gets to creating the object p1 from the Passport class it run an error : "Exception in thread "main" java.lang.NullPointerException". However, when I change in the Passport class to :

 Date copyExpiryDate = new Date(expiryDate.getDay(), 
        expiryDate.getMonth(), expiryDate.getYear());

it workes. anyone knows what I'm doing wrong with the copy constructor? I'll be very thankful for any one who helps!

like image 801
Karoline Avatar asked Jan 03 '23 20:01

Karoline


2 Answers

In the Passport copy constructor you are not creating a copy of the expiration date.

Change

public Passport(Passport passport)
{
  this.name = passport.name;
  this.number = passport.number;
  this.expiryDate = passport.expiryDate;
} 

to

public Passport(Passport passport)
{
  this.name = passport.name;
  this.number = passport.number;
  this.expiryDate = new Date(passport.expiryDate);
}  

The other constructor also has an issue.

public Passport(String name,int number, Date expiryDate)
{
  this.name=name;
  this.number=number;
  Date copyExpiryDate = new Date(this.expiryDate);  
  this.expiryDate = copyExpiryDate;
}

should be

public Passport(String name,int number, Date expiryDate)
{
  this.name=name;
  this.number=number;
  this.expiryDate = new Date(expiryDate);
} 

i.e. you should create a copy of the passed expiryDate, not a copy of this.expiryDate.

like image 88
Eran Avatar answered Jan 05 '23 19:01

Eran


That happens due to

private Date expiryDate; 

expiryDate instance variable it's assigned null and after it passes to

Date copyExpiryDate = new Date(this.expiryDate);

Its something like new Date(null);

That is why it throws NullPointerException.

like image 40
Prathibha Chiranthana Avatar answered Jan 05 '23 17:01

Prathibha Chiranthana