File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Java in General and the fly likes I have some vague concept about Cloneable.... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "I have some vague concept about Cloneable...." Watch "I have some vague concept about Cloneable...." New topic
Author

I have some vague concept about Cloneable....

Waez Ali
Greenhorn

Joined: Jan 10, 2005
Posts: 22
class A13 implements Cloneable {
void disp(){
System.out.println("Cloned method");
}
}
public class clone{
public static void main (String[] args) {
A13 a = new A13();
A13 b = (A13) a.clone();
b.disp();
}
}

Error----------------------------------------------------------------------
clone() has protected access in java.lang.Object
---------------------------------------------------------------------------
To use a clone() on an object, class has to implement Cloneable Interface
I did that but i am not getting error as it says clon() has protected access

I have read that if a class doesn't have "extends" keyword in its
declaration then it implicitly extends Object.

So doesn't that mean, A13 & clone classes are subclasses of Object
so they should have access to clone().

May this concept is vague to me
Plese explain it.

Thanks.
Jeroen Wenting
Ranch Hand

Joined: Oct 12, 2000
Posts: 5093
inheritance doesn't work like that.
You're trying to access a method available to objects of a class and it's siblings from an object that's not a sibling of that class at all.
Just because that method is defined in a common base to them both doesn't mean you're able to do that.


42
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
Originally posted by Waez Ali:
To use a clone() on an object, class has to implement Cloneable Interface
That is a necessary but not sufficient step to making a class cloneable. To encourage you to make a habit of reading them, I'll only say that the JavaDocs are your best friend.

Ohhh, I understand Jeroen's post now. Waez, Were you thinking that since both A13 and clone (the class) extend Object (and thus inherit the clone() method from it) that the clone class should be able to call the clone() method of A13? Or were you hoping that since the class is named exactly like the method that you could call clone()? If we wrong, can you explain what you were thinking so we can clarify? Can you tell it's 5 AM where I am?

In the future, I suggest more expressive class names. Also, it is convention to use InitialCapitalLetters for classes to distinguish them from variableAndMethodNames (similar, but first letter is lowercase) and NAMES_OF_CONSTANTS.
Waez Ali
Greenhorn

Joined: Jan 10, 2005
Posts: 22
hello Jeroen & David,
I am really sorry for that,I just misunderstood
actually I dont have work exp as I am a student & about to pursue my PG. But I like java very much and so preparing for SCJP1.4.
Well i have done(followoing code) what i was trying to do but still I have 3 more questions for you please dont mind.

class TestCloneable implements Cloneable{
public static void main(String arg[]){
TestCloneable obj1 = new TestCloneable();
obj1.display("Orignal");
try{
TestCloneable obj2 = (TestCloneable) obj1.clone();
obj2.display("Clone");
}
catch(CloneNotSupportedException cnse){
System.out.println(cnse);
}
}
protected Object clone()throws CloneNotSupportedException{
return super.clone();
}
void display(String message){
System.out.println("This is "+message);
}
}
output
This is Orignal
This is Clone
----------------
Question?
-1-------------------------------------------------------------------------
Is there any other way to create clone object without overriding clone() method(i mean just using it, as it is available to this class)?If yes then please consider the above code for modification.

Question?
-2-------------------------------------------------------------------------
Please check out the following code

class Amber {
public static void main(String[] args) {
int[][] a = {{1,2},{0,1,2},{-1,0,2}}; // 1
Object[] obj = (Object[])a.clone(); // 2
for(int i = 0; i < obj.length; i++) { // 3
int[] ia = (int[])obj[i]; // 4
System.out.print(ia[i]); // 5
}
}
}
--------
output
112

* How "a"[][](2Dim) can be assigned to "obj"[](OneDim)array at line 2 ?

* What exactly obj array is holding (refrences or elements) ?

* Howcome the output 112 ?


-3-------------------------------------------------------------------
Can you please provide me sample codes or examples that shows need or advantage of making clones.

Please Reply soon

Thanks.
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
Originally posted by Waez Ali:
I am really sorry for that,I just misunderstood
No worries; there's never any need to apologize for asking questions or making mistakes. If my post seemed to be chiding you, please don't take it as such. I enjoy helping people learn; that's why I hang out here.
Is there any other way to create clone object without overriding clone() method(i mean just using it, as it is available to this class)?
Technically no. If you want to be able to have other methods call clone() on an object, you must override Object.clone() and give it public access.

As you can see from your second example (TestCloneable), you can declare clone() to be protected, but then only TestClonable or one of its subclasses can call clone(). I don't think this is what you want in general. If you do it this way, you have to provide some other public method in the class (probably a static helper method) that calls clone() on the actual object.That's just busy work that is best avoided by declaring clone() public in the first place.

Here are a couple pointers about your code that you don't need to understand just yet, but if you do all the better. If these are cnofusing, ignore them for now.
  • Your clone() methods don't need to declare "throws CloneNotSupportedException" since, clearly, you support cloning. Instead, have your clone() method catch CloneNotSupportedException so callers won't have to. This isn't a big deal, however.


  • When overriding a method, you can remove exceptions from the parent's throws list but not add any. This is called "narrowing" since it shrinks (or narrows) the list of possible error conditions the caller must expect.
  • You should generally declare clone() as public so it can be called by other classes.


  • When overriding a method you may declare the access level as more liberal than the parent's method, but not more strict (protected -> public, private -> protected, but not protected -> private). This is called "widening" the access level, though I believe there's a better term (relaxing?) as you're allowing the method to be called by a larger set of classes (widening).
    How "a"[][](2Dim) can be assigned to "obj"[](OneDim)array at line 2 ?
    This is going to get complcated, so hang on!
  • a is an int[][], an array of integer arrays -- each element of the array a (a[0], a[1] and a[2]) is an int[]
  • int[], an array of integers, is a subclass of Object (though not and Object[])
  • obj is an array of Objects, so each element will accept any subclass of Object

  • The above mean "Object[] obj = (Object[])a.clone()" is legal. In the same sense, you cuold also writeThe output should be "a[0][1] = 2".

    Note that the code in the for-loop has the possibility to throw ArrayIndexOutOfBoundsException, but it doesn't in this case. To see this, change the original array declaration by removing one of the elements from the third array {-1,0,2}. It might help to change line 5 toThis will sound circular, but the only reason you'd need to make clones is if you need to make clones. All of the Collection classes (List, Map, and Set implementations) support cloning since that's a very common pattern.

    For example, you have a List of Sales objects (String item, double price, int totalSales) that is kept up-to-date while the application runs. Every so often you want to send the Sales List to another program/file containing only the items that have sold more than 20 items.You clone the original List since you don't want to modify it. Instead, you work on a copy (clone) of the original. After you send it/save it to disk, you throw it away. The original List keeps tracking all sales figures.
    [ January 29, 2005: Message edited by: David Harkness ]
    David Harkness
    Ranch Hand

    Joined: Aug 07, 2003
    Posts: 1646
    Another related concept to cloning is "shallow" versus "deep" cloning. The clone() method of Object does a field-for-field copy, copying the value of each field into the clone. This is the "shallow" copy method. For Java primitives like int and char there isn't any other option. But if the object references other objects, only the references to them are copied. The result is that both the original and cloned objects reference the same set of contained objects.

    For example, if Class A has a reference to class B and you clone an instance of A, both clone and original will reference the same instance of class B.The output will be A deep clone, no the other hand, starts by doing a shallow clone and clones all object references. The result is the the clone will reference all new instances, separating it from the original.

    What if the references go deeper, for example B above has a reference to a C? This is up to whomever writes the clone() method in class B. You can make it go as deep as you like and depends on your needs.

    Adding a clone() method to B (just like A's above) and changing the clone() method in A towill produce this new output:
    Waez Ali
    Greenhorn

    Joined: Jan 10, 2005
    Posts: 22
    Hi David,
    As you said,
    -----------------------------
    Technically no. If you want to be able to have other methods call clone() on an object, you must override Object.clone() and give it public access
    ------------------------------
    I have one question bothering me,

    class Test{// Just like Object
    protected void display()//just like clone() protected
    {
    System.out.println("Helo");
    }
    }
    class CloneTest extends Test{
    public static void main(String arg[]){
    CloneTest obj = new CloneTest();
    obj.display();//???
    }
    }

    as the statement--> obj.display(); Is valid
    then why not statement--> obj.clone();

    I mean if CloneTest implements Cloneable and why not following stm.
    --> CloneTest clone = (CloneTest) obj.clone();

    Why protected clone() can not be called on an object as it is available to that object(as an instance method derived from Obect Class)
    even in your code

    public static TestCloneable clone ( TestCloneable tc ){
    return (TestCloneable) tc.clone();}

    you have called clone() on the object of that class,
    at stmt--> return (TestCloneable) tc.clone()
    But why have you called it indirectly ?I mean why it is not possible to call it like

    TestCloneable tc = new TestCloneable();
    TestCloneable clone = (TestCloneable) tc.clone();

    Please explain it David.

    Thanks.
    David Harkness
    Ranch Hand

    Joined: Aug 07, 2003
    Posts: 1646
    It all depends on what class is calling obj.clone(). If the caller is the same class or a subclass of obj's class, it's okay. If not, the compiler will not allow it.

    In your latest example, I added "CloneTest obj2 = (CloneTest) obj.clone();" to the main() method and it works fine. I had to declare the main() threw Exception since I don't catch CloneNotSupportedException, but we already covered that and it's unrelated to public/protected.

    In my TestCloneable example, I put the code that called clone(), "TestCloneable clone = TestCloneable.clone(original);" outside the TestCloneable class. I wasn't clear, but I was implying that it was in a totally unrelated class.

    A main() method in TestCloneable or a subclass of it would not have to use the static clone() method I added but could call clone() on the object directly.

    Here's a more explicit example that covers all three cases that I can think of.
    [ January 30, 2005: Message edited by: David Harkness ]
    Waez Ali
    Greenhorn

    Joined: Jan 10, 2005
    Posts: 22
    Hello David,
    When I try to compile your code it is showing two errors.
    1 - as you have commented.
    2 - as follows

    B b = new B();
    B bClone = (B) b.clone(); // ok, C is subclass of B
    error-> ^clone() has protected access in Object class.

    This error is really bothering me.I've also tried following declaration

    class B implements Cloneable { }

    for class B but still it does nothing.

    Same thing i have been trying since from my first example.
    please reply me soon about this error.

    And thank you very much David for such a good explanation of Multi-Dim array question and helping me to learn about this Clone()

    Thanks
    David Harkness
    Ranch Hand

    Joined: Aug 07, 2003
    Posts: 1646
    Originally posted by Waez Ali:
    B bClone = (B) b.clone(); // ok, C is subclass of B
    error-> ^clone() has protected access in Object class.
    Wow, I tried it too and couldn't make it work without overriding clone(). My only guess is that the compiler is coded to understand that Object.clone() must be overridden to be accessible. The method is native, but I don't see how that should make a difference.

    I played around with a fwe variations and came up with this as the final one:Notice that B's clone() method is protected -- just like Object's. Given that, they should either both compile o rboth fail, but that's not the case. I looked this up in the JLS and it makes no mention of it. Indeed it says
    The clone method is implemented by the class Object as a convenient, general utility for subclasses that implement the interface Cloneable, possibly also overriding the clone method

    Here are a couple links on the subject of cloning ni Java:
  • Cloneable Does Not Implement Clone -- c2.com, always a good source
  • Controlling Cloneability from Thinking in Java
  • Java Language Specification about Object.clone()
  • You're welcome, and thanks for starting an interesting conversation. It's nice to know that I can still learn random bits about Java.
    [ January 30, 2005: Message edited by: David Harkness ]
    David Harkness
    Ranch Hand

    Joined: Aug 07, 2003
    Posts: 1646
    Ernest Friedman-Hill solved the issue in this post/
    Waez Ali
    Greenhorn

    Joined: Jan 10, 2005
    Posts: 22
    Hello David,

    Yes I got it.
    Well I am very happy today,bkz I got to learn this cool concept of "protected".It became possible just bkz of you sir.
    Thank you very much for your coopration
    and thanks to Ernest Friedman-Hill also.
    bye
    David Harkness
    Ranch Hand

    Joined: Aug 07, 2003
    Posts: 1646
    Thank you too! We both learned, and any day I can say that is a truly wonderful day indeed.
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: I have some vague concept about Cloneable....