Results 1 to 4 of 4
  1. #1
    frenk_castle is offline Member
    Join Date
    Mar 2010
    Location
    Belgrade, Serbia
    Posts
    27
    Rep Power
    0

    Default Clone method question

    I develoloped this rather simple class that implement one item of material.

    Java Code:
    /**
     * 
     */
    package practice;
    
    /**
     * @author Ivan Dejanovic
     *
     */
    public class Material {
    	private int count;
            private String fisName;
            private String fisCode;
            private String name;
            private String nameAux;
        
            public Material() {
        	        count = 0;
    		fisName = new String("");
    		fisCode = new String("");;
    		name = new String("");;
    		nameAux = new String("");;
    	}
    
    	public Material(int count, String fisName, String fisCode, String name,	String nameAux) {		
    		this.count = count;
    		this.fisName = new String(fisName);
    		this.fisCode = new String(fisCode);
    		this.name = new String(name);
    		this.nameAux = new String(nameAux);
    	}
    	
    	public Material (Material material) {
    		count = material.getCount();
    		fisName = new String(material.getFisName());
    		fisCode = new String(material.getFisCode());
    		name = new String(material.getName());
    		nameAux = new String(material.getNameAux());
    	}
    
    	/**
    	 * @return the count
    	 */
    	public int getCount() {
    		return count;
    	}
    
    	/**
    	 * @param count the count to set
    	 */
    	public void setCount(int count) {
    		this.count = count;
    	}
    
    	/**
    	 * @return the fisName
    	 */
    	public String getFisName() {
    		return fisName;
    	}
    
    	/**
    	 * @param fisName the fisName to set
    	 */
    	public void setFisName(String fisName) {
    		this.fisName = fisName;
    	}
    
    	/**
    	 * @return the fisCode
    	 */
    	public String getFisCode() {
    		return fisCode;
    	}
    
    	/**
    	 * @param fisCode the fisCode to set
    	 */
    	public void setFisCode(String fisCode) {
    		this.fisCode = fisCode;
    	}
    
    	/**
    	 * @return the name
    	 */
    	public String getName() {
    		return name;
    	}
    
    	/**
    	 * @param name the name to set
    	 */
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	/**
    	 * @return the nameAux
    	 */
    	public String getNameAux() {
    		return nameAux;
    	}
    
    	/**
    	 * @param nameAux the nameAux to set
    	 */
    	public void setNameAux(String nameAux) {
    		this.nameAux = nameAux;
    	}
    	
    	public Material clone() {
    		return new Material(this);
    	}
    }
    Originally Eclipse generated the second constructor like this:

    Java Code:
    public Material(int count, String fisName, String fisCode, String name,	String nameAux) {		
    		this.count = count;
    		this.fisName = fisName;
    		this.fisCode = fisCode;
    		this.name = name;
    		this.nameAux = nameAux;
    	}
    I don't know if clone is automatically called for Strings but if constructor code was left like this my understanding is that if I invoke it with

    Java Code:
    Material m = new Material (someCount, someFisName, someFisCode, someName, someNameAux);
    And then change for instance someName then name field in the m class will also change since they are references to the same variable in memory.

    My understandingis that when you assign variables in Java that are not primitive variables Java just make both references "point" to same memory variable. To make two distinct variables that can be changed separatelly you need to use clone method.

    I wrote the clone method of Material class under assumtion that I understood every thing about clone ok.

    First Question is: Am I understanding everything about cloning ok based of what I wrote here?

    Second Question: Is my implementation of the clone method ok? I read that when implementing a clone method you need to create a brand new object set its fields to have same values as the objcet you are cloning and then return that new object.

    Third Question: As far as I understood clone, equals, toString and hashCode are methods of the Object class that every new class made by the programmer should reimplement. Is this true? Should some other classes be reimplemented also, or maybe some of these classes shouldn't be reimplemened. Is there some recomendations on the net regarding this and recommendations how reimplementing should be done. Just a link to a good reference will be enough for me.

  2. #2
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,097
    Rep Power
    20

    Default

    With most other objects you'd be correct, in that changing a value inside it will be reflected in all other copies of the erference to this object. For example:

    Java Code:
    public class Blah {
       private int someInt;
        //  etc etc.
    }
    If there were several references a a single Blah object and, through one of those references, the value of someInt was changed, this would be visible through the other references...since they are all looking at the same thing.

    However, you're talking about Strings...and Strings are immutable, which means the data inside a String object cannot change. So this can't actually happen to them...assigning new String() in this case achieves nothing.

    So you were on the right track, you just happened to pick one of the handful of base classes that it doesn't apply to (the primitive wrappers like Integer and Double are similar).

    Hopefully that covers 1 and 2.

    As for 3, well..it depends. There are a lot of classes (like controllers, daos and the like) that it would be pointless providing implementations of those methods, for example. Most things it'll be obvious whether you need to implement those things (and if you implement one of hashCode or equals, then you should implement the other as well in general).

  3. #3
    frenk_castle is offline Member
    Join Date
    Mar 2010
    Location
    Belgrade, Serbia
    Posts
    27
    Rep Power
    0

    Default

    Thanks for your help. It is really appreciated. After I already posted here I continued googling the net in order to understand deep and shallow copying and cloning in Java. I reasiled than that my example with Strings was unfortunate. I found most of the answer I was looking for.

    My main concern is that I am required to write several library classes that will be used in developing several applications. I would like to develop these classes as better as I can so that later other people can use them with out much problems.

    Problem can be seen in this simple class:

    Java Code:
    class DateTest
    {
    	private GregorianCalendar date;
    	
    	public DateTest()
    	{
    		date = new GregorianCalendar();
    	}
    	
    	public GregorianCalendar getDate()
    	{
    		return date;
    	}
    	
    	public void setDate(GregorianCalendar date)
    	{
    		this.date = date;
    	}
    }
    If I use this class in the following fashion

    Java Code:
    GregorianCalendar date1 = new GregorianCalendar();
    date1.set(2010, 4, 9);
    DateTest dateTest = new DateTest();
    dateTest.setDate(date1);
    date1.set(2010, 4, 10); //I am braking ecaptulation here and changing the date field of the dateTest class also
    
    GregorianCalendar date2 = new GregorianCalendar();
    date2 = dateTest.getDate();
    date2.set(2010, 4, 9); //Braking encaptulation again and changing the date field of the dateTest class also
    This is the main reason I asked about cloning to prevent this from happening. Solution that I came up with is to modify the DateTest class in the following fashion

    Java Code:
    class DateTest
    {
    	private GregorianCalendar date;
    	
    	public DateTest()
    	{
    		date = new GregorianCalendar();
    	}
    	
    	public GregorianCalendar getDate()
    	{
    		return new GregorianCalendar(date);
    	}
    	
    	public void setDate(GregorianCalendar date)
    	{
    		this.date = new GregorianCalendar(date);
    	}
    }
    Now user can use the class and can not change the value of date field except by calling setDate method. This class is rather simple but I have to implement several more complicated classes that have the same problem. I have properties for which I would like to define setter and getter methods and I don't want to worry about users of my class that may accidentally change the values in my class in the above stated fashion.

    I can use this solution in developing my classes but it raises the question about the overhead. I want my classes to be as idiot proof as I can make them, but they need to work reasonably well and fast.

    Mister Cay S. Horstmann wrote in his book that only 5% of standard Java library classes implement cloning. Now is this problem just in my head and I don't need to worry to much about it or are there some specifications on how to handle this.

    I spent years programing in C++ and there you solve this by passing a value or a pointer so you specifically define what you what method to be able to do.

    So am I making to big deal out of this or is this a real problem with hopefully better solution than the one I came up with?

    Thanks in advance

  4. #4
    Tolls is offline Moderator
    Join Date
    Apr 2009
    Posts
    12,097
    Rep Power
    20

    Default

    Your example is a good one this time...:)

    This is one of the things that something like Findbugs flags up, that is stuff that breaks encapsulation. Date is one of the common ones for it to flag in fact, and it will recommend doing just what you're doing, in the Date case using its clone() method. Actually, Calendar (and GregorianCalendar) have clone methods.

    If, as you're doing, we're talking a generic library then it may be advisable to provide everything you can for things that are...well...obviously Things, rather than controllers and the like.

    If that makes any sense...

Similar Threads

  1. need help with question(method & array)
    By highschool in forum New To Java
    Replies: 5
    Last Post: 02-10-2010, 05:06 PM
  2. method question
    By xplayerr in forum New To Java
    Replies: 7
    Last Post: 11-11-2009, 04:13 PM
  3. Simple Method Question
    By Froz3n777 in forum New To Java
    Replies: 2
    Last Post: 02-13-2008, 02:39 AM
  4. clone method
    By javaplus in forum New To Java
    Replies: 2
    Last Post: 01-30-2008, 09:47 AM
  5. clone method
    By gapper in forum New To Java
    Replies: 1
    Last Post: 01-20-2008, 08:46 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
  •