Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Object copying
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Implementation == Nearly all [[object-oriented]] [[programming language]]s provide some way to copy objects. As most languages do not provide most objects for programs, a programmer must define how an object should be copied, just as they must define if two objects are identical or even comparable in the first place. Many languages provide some default behavior. How copying is solved varies from language to language, and what concept of an object it has. === Lazy copy === A lazy copy is an implementation of a deep copy. When initially copying an object, a (fast) shallow copy is used. A counter is also used to track how many objects share the data. When the program wants to modify an object, it can determine if the data is shared (by examining the counter) and can do a deep copy if needed. Lazy copy looks to the outside just as a deep copy, but takes advantage of the speed of a shallow copy whenever possible. The downside are rather high but constant base costs because of the counter. Also, in certain situations, [[circular reference]]s can cause problems. Lazy copy is related to [[copy-on-write]]. === In Java === The following presents examples for one of the most widely used object-oriented languages, [[Java (programming language)|Java]], which should cover nearly every way that an object-oriented language can treat this problem. Unlike in C++, objects in Java are always accessed indirectly through [[reference (computer science)|references]]. Objects are never created implicitly but instead are always passed or assigned by a reference variable. (Methods in Java are always ''pass by value'', however, it is the value of the reference variable that is being passed.)<ref name="Passing Information to a Method or a Constructor">{{cite web|title=Passing Information to a Method or a Constructor|url=http://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html|access-date=8 October 2013}}</ref> The [[Java virtual machine|Java Virtual Machine]] manages [[garbage collection (computer science)|garbage collection]] so that objects are cleaned up after they are no longer reachable. There is no automatic way to copy any given object in Java. Copying is usually performed by a [[clone (Java method)|clone() method]] of a class. This method usually, in turn, calls the clone() method of its parent class to obtain a copy, and then does any custom copying procedures. Eventually this gets to the clone() method of <code>Object</code> (the uppermost class), which creates a new instance of the same class as the object and copies all the fields to the new instance (a "shallow copy"). If this method is used, the class must implement the {{Javadoc:SE|java/lang|Cloneable}} marker interface, or else it will [[exception handling|throw]] a "Clone Not Supported Exception". After obtaining a copy from the parent class, a class' own clone() method may then provide custom cloning capability, like deep copying (i.e. duplicate some of the structures referred to by the object) or giving the new instance a new unique ID. The return type of clone() is <code>Object</code>, but implementers of a clone method could write the type of the object being cloned instead due to Java's support for [[covariant return types]]. One advantage of using clone() is that since it is an [[method overriding (programming)|overridable method]], we can call clone() on any object, and it will use the clone() method of its class, without the calling code needing to know what that class is (which would be needed with a copy constructor). A disadvantage is that one often cannot access the clone() method on an abstract type. Most [[interface (object-oriented programming)|interfaces]] and [[abstract class]]es in Java do not specify a public clone() method. Thus, often the only way to use the clone() method is if the class of an object is known, which is contrary to the abstraction principle of using the most generic type possible. For example, if one has a List reference in Java, one cannot invoke clone() on that reference because List specifies no public clone() method. Implementations of List like Array List and Linked List all generally have clone() methods, but it is inconvenient and bad abstraction to carry around the class type of an object. Another way to copy objects in Java is to [[serialization|serialize]] them through the {{Javadoc:SE|java/io|Serializable}} interface. This is typically used for [[persistence (computer science)|persistence]] and [[wire protocol]] purposes, but it does create copies of objects and, unlike clone, a deep copy that gracefully handles cycled graphs of objects is readily available with minimal effort from a programmer. Both of these methods suffer from a notable problem: the [[constructor (computer science)|constructor]] is not used for objects copied with clone or serialization. This can lead to bugs with improperly initialized data, prevents the use of [[final (Java)|<code>final</code>]] member fields, and makes maintenance challenging. Some utilities attempt to overcome these issues by using reflection to deep copy objects, such as the deep-cloning library.<ref>[https://code.google.com/p/cloning/ Java deep-cloning library]</ref> === In Eiffel === Runtime objects in [[Eiffel (programming language)|Eiffel]] are accessible either indirectly through [[reference (computer science)|references]] or as ''expanded'' objects which fields are embedded within the objects that use them. That is, fields of an object are stored either [[Internal storage|externally or internally]]. The Eiffel class <code lang="eiffel">ANY</code> contains features for shallow and deep copying and cloning of objects. All Eiffel classes inherit from <code lang="eiffel">ANY</code>, so these features are available within all classes, and are applicable both to reference and expanded objects. The <code lang="eiffel">copy</code> feature effects a shallow, field-by-field copy from one object to another. In this case no new object is created. If <code lang="eiffel">y</code> were copied to <code lang="eiffel">x</code>, then the same objects referenced by <code lang="eiffel">y</code> before the application of <code lang="eiffel">copy</code>, will also be referenced by <code lang="eiffel">x</code> after the <code lang="eiffel">copy</code> feature completes. To effect the creation of a new object which is a shallow duplicate of <code lang="eiffel">y</code>, the feature <code lang="eiffel">twin</code> is used. In this case, one new object is created with its fields identical to those of the source. The feature <code lang="eiffel">twin</code> relies on the feature <code lang="eiffel">copy</code>, which can be redefined in descendants of <code lang="eiffel">ANY</code>, if needed. The result of <code lang="eiffel">twin</code> is of the anchored type <code lang="eiffel">like Current</code>. Deep copying and creating deep twins can be done using the features <code lang="eiffel">deep_copy</code> and <code lang="eiffel">deep_twin</code>, again inherited from class <code lang="eiffel">ANY</code>. These features have the potential to create many new objects, because they duplicate all the objects in an entire object structure. Because new duplicate objects are created instead of simply copying references to existing objects, deep operations will become a source of performance issues more readily than shallow operations. === In other languages === In [[C Sharp (programming language)|C#]], rather than using the interface <code>ICloneable</code>, a generic extension method can be used to create a deep copy using reflection. This has two advantages: First, it provides the flexibility to copy every object without having to specify each property and variable to be copied manually. Second, because the type is generic, the compiler ensures that the destination object and the source object have the same type. In [[Objective-C]], the methods <code>copy</code> and <code>mutableCopy</code> are inherited by all objects and intended for performing copies; the latter is for creating a mutable type of the original object. These methods in turn call the <code>copyWithZone</code> and <code>mutableCopyWithZone</code> methods, respectively, to perform the copying. An object must implement the corresponding <code>copyWithZone</code> method to be copyable. In [[OCaml]], the [[library (computing)|library]] function [http://caml.inria.fr/pub/docs/manual-ocaml/libref/Oo.html#VALcopy Oo.copy] performs shallow copying of an object. In [[Python (programming language)|Python]], the library's copy module provides shallow copy and deep copy of objects through the <code>copy()</code> and <code>deepcopy()</code> functions, respectively.<ref>[https://docs.python.org/library/copy.html Python copy module]</ref> Programmers may define special methods <code>__copy__()</code> and <code>__deepcopy__()</code> in an object to provide custom copying implementation. In [[Ruby (programming language)|Ruby]], all objects inherit two methods for performing shallow copies, [https://docs.ruby-lang.org/en/master/Kernel.html#method-i-clone clone] and [https://docs.ruby-lang.org/en/master/Object.html#method-i-dup dup]. The two methods differ in that <code>clone</code> copies an object's tainted state, frozen state, and any [[singleton pattern|singleton]] methods it may have, whereas <code>dup</code> copies only its tainted state. Deep copies may be achieved by dumping and loading an object's byte stream or YAML serialization.[http://www.ruby-doc.org/docs/ProgrammingRuby/html/classes.html#S5] Alternatively, you can use the deep_dive gem to do a controlled deep copy of your object graphs. [https://rubygems.org/gems/deep_dive] In [[Perl]], nested structures are stored by the use of references, thus a developer can either loop over the entire structure and re-reference the data or use the <code lang='perl'>dclone()</code> function from the module [https://metacpan.org/module/Storable Storable]. In [[Visual Basic for Applications|VBA]], an assignment of variables of type <code>Object</code> is a shallow copy, an assignment for all other types (numeric types, String, user defined types, arrays) is a deep copy. So the keyword <code>Set</code> for an assignment signals a shallow copy and the (optional) keyword <code>Let</code> signals a deep copy. There is no built-in method for deep copies of Objects in VBA.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)