• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

why clone() ?

 
Ranch Hand
Posts: 360
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Can you show me the real example of usage of the clone() method? Or whats the reason for this method?

Thanks in advance for your replies
 
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can use it to copy arrays:

If array had been an instance of String[], for example, so will copy.
 
Pavel Kubal
Ranch Hand
Posts: 360
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well tank's....I almost forgot that I can override protected method with public one. Now it makes sense
 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Pavel Kubal:
Now it makes sense



For a moment, consider the question - What exactly makes sense about copying array elements here and there? Let's look at an array.

An array is a construct that exposes a contract containing three operations. These operations are symbiotic - they cannot be separated. You can define these operations as:
1. E get(int) signals NoSuchIndex
2. void set(E, int) signals NoSuchIndex
3. int getLength
You can formally express the requirement of each operation, but paraphrasing is easier in communication.

The getLength operation is monadic - it forever returns the same value.
The set operation exists to have an observbable side effect on the get operation. In other words, there is a unidirectional relationship from the set operation and the get operation - the set operation has no legitimate existence without the get operation. The get operation may exist in isolation - it is not monadic. The get or set operation may signal to the client the inability to perform the requested operation - the signal name is NoSuchIndex. This signal isused in the event that the client exceeds the permitted bounds (which can be found through the getLength) operation.

There is nothing (not quite true - see below) more to an array contract. How do you produce a different contract implementation with its own identity? Simply, how do you copy an array? You *must* copy elements since arrays are bound by a certain model of representation - this is an abstraction leak that is intrinsic to arrays. In fact, if arrays were nothing more than the above contract, you could implement a "unique contract implementation identity copy" without ever copying elements. Performance bigotry aside, the biggest benefit is that you have met your requirements with greater accuracy by eliminating excess - clients never know, or care, about how you have met their requirement (remember, this was not to copy an array, but to obtain a unique contract implementation identity representing the same "state" of some other contract).

This is exactly the premise that is used for net.tmorris.adt.sequence.Sequence[1] and since the type is immutable (all operations monadic), there is never a legitimate use case for acknowledging contract implementation identity. You can perform, for example, an "append" using net.tmorris.adt.sequence.AppendSequence[2] to be provided with a Sequence contract implementation that appears to have had elements appended.

The question arises, if Sequence is immutable, and I get a Sequence that has a greater length with additional elements, how can an element copy *not* occur? The problem here is that the premise of the question is contrived. Specifically, this part "I get a Sequence that has a greater length with additional elements". This did not occur at all since this is an invalid requirement. I merely obtain a contract implementation identity that met some formal requirement. That I have applied additional context by referring to "additional elements" or whatever it might be, is purely for my own convenience in conceptualisation of the software at hand and unrelated. It is important that it be understood the limitations of such a conceptualisation.

That ends my rant. Bye
[ March 09, 2006: Message edited by: Tony Morris ]
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[1] http://contractualj.com/api/net/tmorris/adt/sequence/Sequence.html
[2] http://contractualj.com/api/net/tmorris/adt/sequence/AppendSequence.html
 
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow.. Tony your reply was just too good.

To add to your reply...

Be careful with usage of Clone as it does only a Shalow Copy.!!
 
Jeff Albertson
Ranch Hand
Posts: 1780
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Another thing one could mention about the clone methods for array types (which has nothing to do with clone per se) is that in 1.5 they make use of covariant return types. This means that the signature for String[]'s clone, for example, is:

String[] clone()

So:
 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Apart from normal use of clone as specified Sun and Others, one can use clone innovatively for creating classes in runtime without reflection,etc.

This can be really useful for a case of Classes(various strategies) -- which are derived from a common base class, to be executed for different conditions(strategies)

As sun's clone is too-many if's-but's(for good cause/safety), I have implemented my-own close with an hierarchy of classes which do use creative use of clone. I named my method to create(instead of clone and to stop its unwanted checks/restrictions in my code). I not here saying clone can't be used in my case -- what I am suggesting is another way using clone in practical applications.


So concept is like this:
  • Have a parent class have an abstract methods in Base-class with create method and some doJob/run,preJob/postJob methods for doing real work
  • Let is child class implement the create method which will do a new of that child class . Also child class implements some get/set methods and doJob/run for doinf real-work.
  • When JVM has started , register of all child classes in static Map with public methods to get an instance of that class(with a key of string/integer/some-key) . This could be also from a property file with class-names versus some string/integer/some-key
  • In a class where we need to create different child class for different strategy, get the instance of child-class by passing appropriate key.
  • Now create appropriate child class by calling create method. Do any pre processing in that child class instance by using preJob. Then call doJob/doJob/run. After the that call postJob.




  • By use in this way one can add more strategies or handlers(without using Reflection/switch case statements).


    Same methodolgy can applied on other languages -- C,C++,etc
     
    author and iconoclast
    Posts: 24207
    46
    Mac OS X Eclipse IDE Chrome
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You're describing a sort of degenerate "Abstract Factory" pattern; usually the factory class (the one with the "create" method) is a separate class from the product class (the one that is created.) See here for more of a description.
     
    Mahadevan Gorti SS
    Greenhorn
    Posts: 18
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Ernest Friedman-Hill:
    You're describing a sort of degenerate "Abstract Factory" pattern; usually the factory class (the one with the "create" method) is a separate class from the product class (the one that is created.) See here for more of a description.



    As I said earlier, you can use clone if you can.

    Definetely I used "Abstract Factory" pattern, but it is not a degenrate case . Even in ""Abstract Factory" pattern case, how one can generate classes in runtime with these conditions these may depends on restrictions on practical situation that arised in my case)
  • One cannot use Reflection -- for performace reasons
  • One cannot implement Cloneable interface in the class heirarchy( the said base/some-sub classes cannot implement Cloneable interface)
  • Similiar code/pattern should be used in corresponding C/C++ code(that complements java code)
  • Use of switch case in "Abstract Factory" implementation is prohibited -- for obvious reasons of long term maintainance issues
  • Use of if-else-statements in "Abstract Factory" implementation is prohibited -- for obvious reasons of long term maintainance issues



  • So tell me if you have any other method/way/suggestion to do same thing in "Abstract Factory" with above conditions.
     
    Wanderer
    Posts: 18671
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Mahadevan - could you please take another look at our display name policy and then edit your display name to include a first and last name? Not an abbreviation and/or name of a company or organization. Thanks.
     
    Ernest Friedman-Hill
    author and iconoclast
    Posts: 24207
    46
    Mac OS X Eclipse IDE Chrome
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Mahadevan GSS:
    Definetely I used "Abstract Factory" pattern, but it is not a degenrate case . So tell me if you have any other method/way/suggestion to do same thing in "Abstract Factory" with above conditions.



    First, it sounds like you had an emotional response to the word "degenerate", as if it were an insult. It's not -- I'm using the word in its mathematical sense of "multiple things collapsed into one."

    In the "Factory Pattern", one "Factory" class could make different "Product" classes bases on some input parameter. Usually the creational method is a static method. Your list of objections above are mostly aimed at ways that the "Factory Pattern" can be implemented, and they are certainly valid objections. These objections are all addressed, actually, by the "Abstract Factory Pattern."

    Despite the similar name, the "Abstract Factory Pattern" is a different pattern altogether. In that pattern, you define a "AbstractFactory" interface, often with many different "create" methods that create a family of "Product" classes. Then different implementations of the AbstractFactory create different implementations of the Product classes. The classic example of Product families are GUI widgets: you might have an AWTFactoryImple, a SwingFactoryImpl, and an SWTFactoryImpl. The createButton() method in AbstractFactory would be implemented to create a java.awt.Button in the AWTFactoryImpl, a JButton in the SwingFactoryImpl, etc. Similarly, the same AbstractFactory could have a createList(), createComboBox(), and other methods.

    So I called your implementation "degenerate" because the AbstractFactory and the Product are the same class, and because there is only one create() method -- not because it was bad or perverted in some way.
     
    Ranch Hand
    Posts: 1683
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Can you show me the real example of usage of the clone() method? Or whats the reason for this method?


    Suppose you have a method which returns a reference to a mutable object (let us call it A). If you do not want the caller to change A, and cannot make A immutable, then you should defensively copy A and return a reference to the copy of A. Cloning is one way of making that copy of A, with the caveat that the cloning is shallow, not deep.
     
    Jeff Albertson
    Ranch Hand
    Posts: 1780
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Originally posted by Roger Chung-Wee:

    Cloning is one way of making that copy of A, with the caveat that the cloning is shallow, not deep.



    I'm not sure "cloning => shallow". The javadoc for Object.clone states (my emphasis):

    By convention, the object returned by this method should be independent of this object (which is being cloned). To achieve this independence, it may be necessary to modify one or more fields of the object returned by super.clone before returning it. Typically, this means copying any mutable objects that comprise the internal "deep structure" of the object being cloned and replacing the references to these objects with references to the copies. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.clone need to be modified.
     
    Jim Yingst
    Wanderer
    Posts: 18671
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I'd say that the default implementation of clone() inherited from Object does give you a shallow clone. If you override it, you can get a deep clone - or something in between.
     
    Ranch Hand
    Posts: 1170
    Hibernate Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    this is precisely why I do not make clone public. clone has an implementation that people expect when they see the method. shallow copy. But the contract says it does not have to be shallow. So when folks see clone rightfully they don't exactly know what to expect in return. and its not helpful if everyone returns something different from a standard method IMHO.

    I always do something like so


    [ March 24, 2006: Message edited by: Mr. C Lamont Gilbert ]
     
    Greenhorn
    Posts: 2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Java Newbie Here!

    Hi all, read your post with great interest. I am new to Java and am trying to get my head round the uses of the Clone function.

    I was hoping someone might be able to put me on the right track, cause the CBT software i have doesn't really cover this in enough depth for me.

    I have read and understand how to use the Clone Method, but can someone please answer the following....

    In what circumstances would you use cloning?

    Any help appreciated.

    Cheers
     
    (instanceof Sidekick)
    Posts: 8791
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Clone gives you a copy of an object at a point in time. You might use it if you want a copy you can modify without affecting the original, or one that will remain unchanged even if another thread modifies the original.

    We also recently discussed with the Prototype pattern.
     
    David Halliday
    Greenhorn
    Posts: 2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Legend!

    Thanks, thought it might be the case that it ensured the original copy was not being altered. I can imagine this being useful in arrays particularly.

    Many thanks again.

    David
     
    reply
      Bookmark Topic Watch Topic
    • New Topic