Cloneable Interface and Inner Classes - ClassCastException

I'm learning about interfaces, clone methods, and inner classes and have encountered a problem in a project.  First, we have a class that represents a person as an object. This implements the Cloneable interface.  The class Date is an inner class of Person and represents a date and includes a bunch of methods for formatting and such.  I was supposed to write clone() methods using the Cloneable interface and don't encounter any compile errors.  However, when I try to use the clone() method, a runtime error occurs.  It throws a ClassCastException at the point marked below.  I was wondering if anyone could help me find errors in the code or have ny helpful hints or information on the subject?

Here are the important bits and the constructors:

public class Person implements Cloneable {
  private String name;
  private Date born;
  private Date died;
  public Object clone() {
    try {
      Person copy = (Person)super.clone();
      copy.name = name;
      copy.born = (Date) born.clone();
      copy.died = (Date) died.clone();
      return copy;
    }
    catch (CloneNotSupportedException e) {
      return e;
    }
  }
  public Person() {}
  public Person(String initialName, Date birthDate, Date deathDate) {
    if (consistent(birthDate, deathDate)) {
      name = initialName;
      born = new Date(birthDate);
      if (deathDate == null)
        died = null;
      else
        died = new Date(deathDate);
    }
    else {
      System.out.println("Inconsistent dates. Aborting.");
      System.exit(0);
    }
  }
  public Person(Person original) {
    if (original == null) {
      System.out.println("Fatal error.");
      System.exit(0);
    }
    name = original.name;
    born = new Date(original.born);
    if (original.died == null)
      died = null;
    else
      died = new Date(original.died);
  }
****other methods****
********Inner Class:***   public class Date {
      private String month; //always 3 letters long, as in Jan, Feb, etc.
      private int day;
      private int year; //a four digit number.
      public Date() {
        month = "Jan";
        day = 1;
        year = 1000;
      }
   public Object clone() {
     try {
       Date copy = (Date)super.clone();
       copy.month = month;
       copy.day = day;
       copy.year = year;
       return copy;
     }
     catch (CloneNotSupportedException e) {
       return e;
     }
   }
   public Date(int monthInt, int day, int year) {
     setDate(monthInt, day, year);
   }
   public Date(String monthString, int day, int year) {
     setDate(monthString, day, year);
   }
   public Date(int year) {
     setDate(1, 1, year);
   }
   public Date(Date aDate) {
     if (aDate == null) { //Not a real date.
       System.out.println("Fatal Error.");
       System.exit(0);
     }
     month = aDate.month;
     day = aDate.day;
     year = aDate.year;
   }
***Other Methods***
}

-----------------------------------------------------------------------
Driver program:

public class PersonDemo {
  public static void main(String[] args) {
******Create a Person object so I can invoke the inner class Date:***    Person p = new Person();
    Person bach = new Person("Johann Sebastian Bach", p.new Date("Mar", 21, 1685),
                             p.new Date("Jul", 28, 1750));
    System.out.println(bach);

******Problem line:***  Person bachTwin = (Person)bach.clone();

******Working Alternative:***//  Person bachTwin = new Person(bach);

    System.out.println("Comparing bach and bachTwin:");
    if (bachTwin == bach)
      System.out.println("Same reference for both.");
    else
      System.out.println("Distinct copies.");
    if (bachTwin.equals(bach))
      System.out.println("Same data.");
    else
      System.out.println("Not same data.");
  }
}

Thank you for your time.  If you need additional code or information, please let me know.
rkjohnson2005Asked:
Who is Participating?
 
objectsConnect With a Mentor Commented:
Also your Date class does not implement CLoneable (which is probaly the case of the problem)
0
 
objectsCommented:
Where is the CCE occurring?
0
 
rkjohnson2005Author Commented:
"Driver program:

public class PersonDemo {
  public static void main(String[] args) {
******Create a Person object so I can invoke the inner class Date:***    Person p = new Person();
    Person bach = new Person("Johann Sebastian Bach", p.new Date("Mar", 21, 1685),
                             p.new Date("Jul", 28, 1750));
    System.out.println(bach);

******Problem line:***  Person bachTwin = (Person)bach.clone();  <<<<<<<<<<<<<<<<HERE IS WHERE THE EXCEPTION IS THROWN

******Working Alternative:***//  Person bachTwin = new Person(bach);" <<<<<<<<<<<<THIS LINE CAUSES NO PROBLEMS (AS FAR AS I CAN TELL) BUT DOESNT USE THE METHODS REQUIRED
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
objectsCommented:
can you post the stack trace for the CCE please.
0
 
rkjohnson2005Author Commented:
I'm not completely sure what the stack trace is - Do you mean this?

java.lang.ClassCastException
      at project_9_.Person.clone(Person.java:36)
      at project_9_.PersonDemo.main(PersonDemo.java:31)
Exception in thread "main"
0
 
objectsCommented:
>   catch (CloneNotSupportedException e) {
>      return e;
>    }

you shouldn't be returning e, if an exception occurs.
Probably should rethrow an appropriate exception
0
 
rkjohnson2005Author Commented:
public class Person {
***
  public Object clone() {
    try {
      Person copy = (Person)super.clone();
      copy.name = name;
>>>>>>>>>LINE 36:      copy.born = (Date) born.clone();
      copy.died = (Date) died.clone();
      return copy;
    }
    catch (CloneNotSupportedException e) {
      return e;
    }
  }

public class PersonDemo {
  public static void main(String[] args) {
    Person p = new Person();
    Person bach = new Person("Johann Sebastian Bach", p.new Date("Mar", 21, 1685),
                             p.new Date("Jul", 28, 1750));
    System.out.println(bach);

LINE 31: >>>>>>>>>>   Person bachTwin = (Person)bach.clone();
0
 
rkjohnson2005Author Commented:
OMG.  That was it.  Date didn't implement Cloneable. Such a simple solution. . . I'm a moron. Thank you so much!
0
 
objectsCommented:
no worries :)
0
All Courses

From novice to tech pro — start learning today.