Results 1 to 5 of 5
  1. #1
    jon80's Avatar
    jon80 is offline Senior Member
    Join Date
    Feb 2008
    Location
    Malta (EU)
    Posts
    211
    Rep Power
    7

    Default [SOLVED] [newbie] Is my method mutable?

    I'm implementing a clone() method and the book reads that I have to clone mutable fields in order to carry out a deep copy.

    What I don't understand is whether HireDay() field in my class is actually mutable:

    1. HireDay is initialized through the constructor for Employee. I guess I could pass a Date object straight away in real life, unless I'm reading from some CSV.
    2. Read only method HireDay(), which should be called getHireDay() by common naming convention, reads from private variable _hireDay.

    imho it is not mutable unless I create a new object.

    Java Code:
    package homenetwork.bkr.training;
    import java.util.*;
    public class Employee extends Person implements Comparable<Employee>, Cloneable {
    	public Employee (String name, double salary, Integer year, Integer month, Integer day)
    	{
    		super(name);
    		this._salary = salary;
    		GregorianCalendar calendar = new GregorianCalendar(year, month -1, day);
    		_hireDay = calendar.getTime();	
    	}
    	
    	public double Salary() {
    		return _salary;
    	}
    	
    	//TODO: Methods should be named:
    	//getHireDay for methods that read information
    	//setHireDay for methods that write information to the object
    	//To review all the classes.
    	public Date HireDay() {
    		return _hireDay;
    	}
    	
    	public String Description() {
    		return String.format("An employee with a salary of €%s", _salary);
    	}
    	
    	public void raiseSalary(double byPercent)
    	{
    		double raise = _salary * byPercent / 100;
    		_salary += raise;
    	}
    	
    	@Override public boolean equals (Object anotherObject) 
    	{
    		if (this == null) return false;
    		
    		if (this == anotherObject) return true;
    	 	
    		if ((!(anotherObject instanceof Employee)) || 
    			(getClass() != anotherObject.getClass()))
    			return false;
    				
    		Employee _employee = (Employee) anotherObject;
    		return	(	(super.Name().equals(_employee.Name()))
    			&& (this._salary == _employee.Salary())
    			&& (this._hireDay.equals(_employee.HireDay())));
    			
    	}
    	
    	@Override public int compareTo(Employee anotherEmployee) {
    		//TODO Introduce some seniority rules	
    		
    		if (anotherEmployee instanceof Employee)
    		{
    			if (_salary < anotherEmployee.Salary()) return -1;
    			if (_salary > anotherEmployee.Salary()) return 1;
    			return EQUAL;
    		}
    		else return ERROR;
    	}
    	
    	public Employee clone () throws CloneNotSupportedException
    	{
    		//call Object.clone()
    		Employee _cloned = (Employee) super.clone();
    				
    		return _cloned;
    		
    	}
    	private final static short EQUAL = 0;
    	private final static int ERROR = 999999;
    	private double _salary;
    	private Date _hireDay;	
    	
    }
    Taking another example:
    Take another example, class Employee, method Salary()
    Salary() can be changed through method raiseSalary()

    Therefore, it is mutable and a deep copy has to be done within the clone() method. However, .clone() cannot be called on a primitive type such as a double, so cloning cannot be done.

    The example in this book provided an example to clone hireDay, which imho is not mutable, so it does not have to be deep copied.

    Java Code:
    package homenetwork.bkr.training;
    
    import java.util.Date;
    
    public class Manager extends Employee implements Cloneable {
    	
    	public Manager (double bonus)
    	{
    		super (null,0,0,0,0);
    		this._bonus = bonus;
    	}
    	
    	/**
    	 * @param	name - Manager's name and surname
    	 * @param   salary - Annual salary (€)
    	 * @param   bonus - Annual performance bonus (€)
    	 * @param   year - year of hire date
    	 * @param	month - month of hire date
    	 * @param	day - day of hire date
    	 */
    	
    	public Manager ()
    	{
    		super (null, 0,0,0,0);
    		this._bonus = 0;
    	}
    	
    	public Manager (String name, double salary, double bonus, int year, int month, int day) 
    	{ 
    		super (name, salary, year, month, day);
    		this._bonus = bonus;
    	}
    	
    	public Manager (String name, double salary, int year, int month, int day) 
    	{ 
    		super (name, salary, year, month, day);
    		this._bonus = 0;
    	}
    	
    	public double Bonus() {
    		return _bonus;
    	}
    	
    	public double Salary()
    	{
    		return (super.Salary() + _bonus);
    	}
    		
    	public Manager clone () throws CloneNotSupportedException
    	{	
    		//call Object.clone()
    		Manager _cloned = (Manager) super.clone();
    
    //clone mutable objects
    [B]cloned._hireDay = (Date) _hireDay.clone() //not mutable, so it should be removed no?[/B]
    		return _cloned;
    	}
    	
    	@Override public boolean equals (Object anotherObject) 
    	{
    		if (this == null) return false;
    		
    		if (this == anotherObject) return true;
    	 	
    		if ((!(anotherObject instanceof Manager)) || 
    			(getClass() != anotherObject.getClass()))
    			return false;
    				
    		Manager _manager = (Manager) anotherObject;
    		return	(	(super.Name().equals(_manager.Name()))
    			&& (super.Salary() == _manager.Salary())
    			&& (super.HireDay().equals(_manager.HireDay()))
    			&& (this._bonus == this._bonus));
    			
    	}
    	
    	private double _bonus;
    
    }
    Last edited by jon80; 05-20-2009 at 03:07 PM. Reason: update

  2. #2
    masijade is offline Senior Member
    Join Date
    Jun 2008
    Posts
    2,571
    Rep Power
    9

    Default

    Well, what if someone calls HireDay() on the clone, then calls setTime() on the returned object?

    If you don't clone _hireDay, that would change the Date in both objects, wouldn't it?

    In oreder for it to be immutable, you missing only one step, and that is to return a copy of _hireDay in the HireDay method, rather than the actual _hireDay reference.

    i.e.
    Java Code:
    	public Date HireDay() {
    		return new Date(_hireDay.getTime());
    	}
    and don't create a setter for it, or it is once again mutable.

  3. #3
    OrangeDog's Avatar
    OrangeDog is offline Senior Member
    Join Date
    Jan 2009
    Location
    Cambridge, UK
    Posts
    838
    Rep Power
    6

    Default

    HireDay() is not a field, it is a method.
    Methods are by definition immutable as you cannot change them once they have been compiled.

    Your fields are EQUAL, ERROR, _salary and _hireDay

    EQUAL and ERROR are constants so don't require copying.
    _salary is a primitive type so only requires copying.
    _hireDay is a Date object so we have to check if it is mutable (the object can me modified once created). Date has various set methods so it is mutable and requires cloning.

    An example of an immutable object is a String, an Integer or a Class.
    Last edited by OrangeDog; 05-20-2009 at 10:05 PM.
    Don't forget to mark threads as [SOLVED] and give reps to helpful posts.
    How To Ask Questions The Smart Way

  4. #4
    jon80's Avatar
    jon80 is offline Senior Member
    Join Date
    Feb 2008
    Location
    Malta (EU)
    Posts
    211
    Rep Power
    7

    Default

    I agree that the Date class is mutable, my pov was that since I cannot modify any instance of the HireDay() given the way I had coded the classes they cannot be changed, unless I use java.lang.reflect to modify my methods. Within this context, that would make all my methods mutable.

  5. #5
    OrangeDog's Avatar
    OrangeDog is offline Senior Member
    Join Date
    Jan 2009
    Location
    Cambridge, UK
    Posts
    838
    Rep Power
    6

    Default

    Talking about mutability of methods makes no sense. One again, HireDay() is a method (which should have the better name of getHireDay()). The field is called _hireDay (and could well do without the _). You cannot change methods even via reflection.

    Just clone the Date object, this prevents future problems if you modify your class, or someone uses reflection.
    Don't forget to mark threads as [SOLVED] and give reps to helpful posts.
    How To Ask Questions The Smart Way

Similar Threads

  1. Another newbie
    By PhHein in forum Introductions
    Replies: 0
    Last Post: 04-22-2009, 01:26 PM
  2. Newbie Help
    By mattkid in forum New To Java
    Replies: 4
    Last Post: 03-25-2009, 04:55 AM
  3. I am newbie
    By Seoplanner in forum Introductions
    Replies: 0
    Last Post: 11-11-2008, 01:22 PM
  4. newbie. Reading a file, deprecated method
    By Roy Gardiner in forum New To Java
    Replies: 2
    Last Post: 10-24-2008, 08:08 PM
  5. :) newbie...........
    By Somitesh Chakraborty in forum Introductions
    Replies: 1
    Last Post: 08-19-2008, 09:00 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •