Jump to content

what happes inside Java. clone method()

- - - - -

  • Please log in to reply
4 replies to this topic

#1
VakhoQ

VakhoQ

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
Hello,

I can use clone() method in Java. I know how to do this well, But I have some question:

1) because of each class is a subclass of Object, we can use methodes of Object class in our subclasses, for example: equals(), clone() and so on;
but, when we use clone() method, why should we need interface Cloneable(), what does it really makes? I have already method in Object class, why should I implement Cloneable interface? Is not it unnecessery?

2) If I have already clone() method, as a Default, in the Object class, why can't I override this method in the subclass if I don't implement Cloneable Intercae? for example: I can override protected finalize() method, but I cant override clone() method if I don't implement Cloneable interface;


3) is not Cloneable interface unnecessary? we dont need any interfaces in finalize(), allocateResources() and so on, why do we need here interface?

4) can i see the source, code, of Object classes?


5) why can't I call to a clone method, without overriding? the method is writen in Object class, I have subclass of Object, so why cant I call to my parent methods? for example i can call to equals() or something other Object methods without overriding too. but not clone();


thanks, a lot :)
GNU/Linux Is the Best.

#2
VakhoQ

VakhoQ

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
any idea?
GNU/Linux Is the Best.

#3
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java
I don't know for sure, just thinking out loud here, but I would assume it's to make the developer think before just start cloning everywhere as you should be careful.

If the cloneable interface was not required. And other developers start cloning Pizzas they may get undesired effect, or be surprised.
public class Pizza{
  private Taste taste;
}
Cloning that would make a copy of Pizza, but they both have a reference to the same Taste object, clone does not clone "children" of the object.
Meaning that changing the Taste of the clone would also change the taste of the original.

Since VERY often this is an undesired 'side-effect' of cloning, as you would probably also want to clone the Taste, it's not really that bad to let it be required by the developer to make it cloneable.
Because then you know, if something is cloneable the developer must have put implements Cloneable there meaning he/she probably thought about this issue / side-effect of cloning.

So if Pizza had implemented Cloneable, the other developers using the pizza class can be 'sure' (assuming the original developer cloned it well) they get a decent-to-work-with clone.

Without the interface requirement you could NEVER be sure the thing you're trying to clone will be cloned well. Since, as you said, it's a method from Object which everyone therefor inherits.



Sometimes it's also just weird to clone stuff. Just like it's sometimes weird to Serialize stuff.

The Serializable interface also has no methods, it's just a marker interface doing nothing but telling this object is Serializable - No requirements.
When is it weird to serialize stuff?
For example threads. Serializing a thread to a file, and deserializing it back later is just plain weird and would never properly succeed.
In my opinion it's equally weird if a developer makes a Singleton for his class and then people could just .clone() the singleton... It's singleton for a reason :P - no guarantees if the Cloneable interface wasn't required.

Quote

If I have already clone() method, as a Default, in the Object class, why can't I override this method in the subclass if I don't implement Cloneable Intercae? for example: I can override protected finalize() method, but I cant override clone() method if I don't implement Cloneable interface;
I don't see why not? You CAN override it, no compiler error, no runtime error.

Quote

can i see the source, code, of Object classes?
Yes, depending on your IDE it's easy.
If you don't have an IDE, you can try docjar.com or open your explorer, where you installed the JDK there should also be a "src.zip" (or .tar or whatever you received on unix :P) which contains all the source files.

Quote

why can't I call to a clone method, without overriding? the method is writen in Object class, I have subclass of Object, so why cant I call to my parent methods? for example i can call to equals() or something other Object methods without overriding too. but not clone();
Again, perfectly possible. Just implement the interface, don't override it and clone ahead ^^

#4
VakhoQ

VakhoQ

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts

VakhoQ said:

why can't I call to a clone method, without overriding? the method is writen in Object class, I have subclass of Object, so why cant I call to my parent methods? for example i can call to equals() or something other Object methods without overriding too. but not clone();

wim DC said:

Again, perfectly possible. Just implement the interface, don't override it and clone ahead

could you give me an example, please? I have compiler error in my following example:

public class testing {	

	public static void main(String Args[]){

			Class1 ref1 = new Class1();

	                Class1 ref2 = (Class1) ref1.clone();

	}

}



class Class1 implements Cloneable{	

	String i;

}



VakhoQ said:

If I have already clone() method, as a Default, in the Object class, why can't I override this method in the subclass if I don't implement Cloneable Intercae? for example: I can override protected finalize() method, but I cant override clone() method if I don't implement Cloneable interface;

wim DC said:

I don't see why not? You CAN override it, no compiler error, no runtime error.

Ok, everything works, and if I remove "implemnts Cloneable" , whether the clone() method is still overridden Object method or not?
public class testing {	

	public static void main(String Args[]){

			Class1 ref1 = new Class1();

			Class1 ref2 = (Class1) ref1.clone();

	}

}



class Class1 implements Cloneable{ // if I remove it	

	String i;

	

	 protected Object clone() {

		return null;

		

	}

}

GNU/Linux Is the Best.

#5
wim DC

wim DC

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 2,084 posts
  • Programming Language:Java, JavaScript, PL/SQL
  • Learning:Java

Quote

could you give me an example, please? I have compiler error in my following example:
The reason that fails is because clone() is protected and you usually override it being public.
Since it's protected and you don't override it, you can only call it from extending classes or from within the class itself or from a class in the same package of Object (= java.lang)

To make your example work, simply move the main method into Class1 (And deal with the error handling (try-catch or throws))
public class testing {    
}




class Class1 implements Cloneable{    
    String i;
    
    public static void main(String Args[]) throws CloneNotSupportedException {
            Class1 ref1 = new Class1();
                    Class1 ref2 = (Class1) ref1.clone();
    }
}
(Or you could make the package java.lang and put your testing class in that, but that would be a bad idea, so read it and forget about it.)
[SIZE=4][B]package java.lang;[/B][/SIZE]


public class testing {    
    public static void main(String Args[]) throws CloneNotSupportedException {
            Class1 ref1 = new Class1();
                    Class1 ref2 = (Class1) ref1.clone();
    }
}




class Class1 implements Cloneable{    
    String i;
}




Quote

Ok, everything works, and if I remove "implemnts Cloneable" , whether the clone() method is still overridden Object method or not?
If you remove implements Cloneable it's still a legal override of the clone method in Object. And as long as you don't do super.clone() in the overridden method nothing will complain.
(Because super.clone() will cause Object's method to run, and that one will check for the interface).
The return null; you have now will work perfectly.

Not calling Object's clone method is considered a bad clone though, and if you want to call super.clone() to get the Object's method to run, it will check for the interface.
So you better just implement Cloneable if you want your class to be cloned in a decent way.



Oh, remember how I said you could see the source? Well, clone is a special one because it's "native". see Java Native Interface - Wikipedia, the free encyclopedia if you're really interested.
Well, you can actually see the source, because what you get to see from Object.java IS the source, but it won't give you much information on how it actually works.

Edited by wim DC, 02 February 2012 - 06:31 AM.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users