//Class Person:
public class Person implements Cloneable, Comparable{
    private String firstName;
    private String lastName;

    //Default constructor
    public Person() {
        firstName = " ";
        lastName = " ";
    }

    //Alternate Constructor
    public Person(String first, String last) {
        setName(first, last);
    }

    //Copy constructor
    public Person(Person original) {
        if(original == null)  {
            System.out.println("Fatal error for this Person.");
            System.exit(0);
        }
        firstName = original.firstName;
        lastName = original.lastName;
    }

    //clone; without this, compile error in client (.clone protected)
    public Object clone() {
        try  {
            return super.clone();
        }
        catch (CloneNotSupportedException e) {
            return null;
        }
    }

    public String toString(){
        return (lastName + ", " + firstName);
    }

    public void printLastFirst() {
        System.out.print(lastName + ", " + firstName);
    }

    public void printFirstLast() {
        System.out.print(firstName + " " + lastName);
    }

    public void setName(String first, String last) {
        firstName = first;
        lastName = last;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public boolean equals(Object obj) {
      if (obj instanceof Person) {
          Person otherPerson = (Person) obj;
          return lastName.equals(otherPerson.lastName) && firstName.equals(otherPerson.firstName);
      }
      else   // not a Person object
          return false;
    }

    public int compareTo(Object otherPerson) {
        Person temp = (Person) otherPerson;
        int compare = lastName.compareTo(temp.lastName);
        if(compare == 0)
            compare = firstName.compareTo(temp.firstName);
        return compare;
    }

}

//Class: ClientPersonClone
public class ClientPersonClone {
    public static void main(String[] args) {
        Person one = new Person("John", "Doe");
        System.out.println("one: " + one);
        Person two = (Person) one.clone();
        System.out.println("Copy one using .clone(). After copy, two: " + two);

        if (one == two)
            System.out.println("Both one and two refer to the same object.");
        else
            System.out.println("one and two DON'T refer to the same object.");
        one.setName("Jane", "Smith");
        System.out.println("Changed one to Jane Smith. After change:");
        System.out.println("one: " + one);
        System.out.println("two: " + two);
    }
}

OUTPUT:

one: Doe, John
Copy one using .clone(). After copy, two: Doe, John
one and two DON'T refer to the same object.
Changed one to Jane Smith. After change:
one: Smith, Jane
two: Doe, John