text:  is the most efficient form of argument passing. This is nice; the default way of doing things is also the most efficient. However, sometimes it’s necessary to be able to treat the object as if it were “local” so that changes you make affect only a local copy and do not modify the outside object. Many programming languages support the ability to automatically make a local copy of the outside object, inside the method. [49] Java does not, but it allows you to produce this effect.
  Pass by value
  This brings up the terminology issue, which always seems good for an argument. The term is “pass by value,” and the meaning depends on how you perceive the operation of the program. The general meaning is that you get a local copy of whatever you’re passing, but the real question is how you think about what you’re passing. When it comes to the meaning of “pass by value,” there are two fairly distinct camps:
  -
  The most likely reason for making a local copy of an object is if you’re going to modify that object and you don’t want to modify the caller’s object. If you decide that you want to make a local copy, you simply use the clone( ) method to perform the operation. This is a method that’s defined as protected in the base class Object and which you must override as public in any derived classes that you want to clone. For example, the standard library class Vector overrides clone( ), so we can call clone( ) for Vector:
  //: Cloning.java // The clone() operation works for only a few // items in the standard Java library. import java.util.*; class Int { private int i; public Int(int ii) { i = ii; } public void increment() { i++; } public String toString() { return Integer.toString(i); } } public class Cloning { public static void main(String[] args) {ability in every class you create, the clone( ) method is protected in the base class Object. Not only does this mean that it’s not available by default to the client programmer who is simply using the class (not subclassing it), but it also means that you cannot call clone( ) via a handle to the base class. (Although that might seem to be useful in some situations, such as to polymorphically clone a bunch of Objects.) It is in effect a way to give you, at compile time, the information that your object is not cloneable – and oddly enough most classes in the standard Java library are not cloneable. Thus, if you say:
  Integer x = new Integer(1); x = x.clone();
  You will get, at compile time, an error message that says clone( ) is not accessible (since Integer doesn’t override it and it defaults to the protected version).
  If, however, you’re in a class derived from Object (as all classes are), then you have permission to call Object.clone( ) because it’s protected and you: virtually always call super.clone( ) and make your clone public.
  You’ll clonability and you want to make a class that’s cloneable. In any classes inherited from your class the clone( ) method is available since it’s not possible in Java to reduce the access of a method during derivation. That is, once a class is cloneable, everything derived from it is cloneable unless you use provided mechanisms (described later) to “turn off” cloning.Implementing the Cloneable interface
  There’s one more thing you need to do to complete the clonability of an object: implement the Cloneable interface. This interface is a bit strange because it’s empty!
  interface Cloneable {}
  The reason for implementing this empty interface is obviously not because you are going to upcast to Cloneable and call one of its methods. The use of interface here is considered by some to be a “hack” because it’s using a feature for something other than its original intent. Implementing the Cloneable interface acts as a kind of a flag, wired into the type of the class.ability was the thought that maybe you didn’t want all types of objects to be cloneable. So Object.clone( ) verifies that a class implements the Cloneable interface. If not, it throws a CloneNotSupportedException exception. So in general, you’re forced to implement Cloneable as part of support for cloning. equivalence, // not object equivalence: if(a == b) System.out.println("a == b"); else System.out.println("a != b"); System.out.println("a = " + a); System.out.println("b = " + b); MyObject c = new MyObject(47); MyObject d = f(c); if(c == d) System.out.println("c == d"); else System.out.println("c != d"); System.out.println("c = " + c); System.out.println("d = " + d); } } ///:~
  First of all, clone( ) must be accessible so you must make it public. Second, for the initial part of your clone( ) operation you should call the base-class version of clone( ). The clone( ) that’s being called here is the one that’s predefined inside Object, and you can call it because it’s protected and thereby accessible in derived classes.
  Object.clone( ) figures out how big the object is, creates enough memory for a new one, and copies all the bits from the old to the new. This is called a bitwise copy , and is typically what you’d expect a clone( ) method to do. But before Object.clone( ) performs its operations, it first checks to see if a class is Cloneable, that is, whether it implements the Cloneable interface. If it doesn’t, Object.clone( ) throws a CloneNotSupportedException to indicate that you can’t clone it. Thus, you’ve got to surround your call to super.clone( ) with a try-catch block, to catch an exception that should never happen (because you’ve implemented the Cloneable interface).
  In LocalCopy, the two methods g( ) and f( ) demonstrate the difference between the two approaches for argument passing. g( ) shows passing by reference in which it modifies the outside object and returns a reference to that outside object, while f( ) clones the argument, thereby decoupling it and leaving the original object alone. It can then proceed to do whatever it wants, and even to return a.
  In main( ), the difference between the effects of the two different argument-passing approaches in the two different methods is tested. The output is:
  a == b a = 12 b = 12 c != d c = 47 d = 48
  It’s important to notice that the equivalence tests in Java do not look inside the objects being compared to see if their values are the same. The == and != operators are simply comparing the contents of the handles. If the addresses inside the handles are the same, the handles are pointing to the same object and are therefore “equal.” So what the operators are really testing is whether the handles are aliased to the same object!
  The effect of Object.clone( ) object’s storage. That is, it doesn’t just make storage and copy an Object – it actually figures out the size of the precise object that’s being copied and duplicates that. Since all this is happening from the code in the clone( ) method defined in the root class (that has no idea what’s being inherited from it), you can guess that the process involves RTTI to determine the actual object that’s being cloned. This way, the clone( ) method can create the proper amount of storage and do the correct bitcopy handles? The following example tests this:
  //: Snake.java // Tests cloning to see if destination of // handles are also cloned. public class Snake implements Cloneable { private Snake next; private char c; // Value of i == number of segments Snake(int i, char x) { c = x; if(--i > 0) next = new Snake(i, (char)(x + 1)); } void increment() { c++; if(next != null) next.increment(); } public String toString() { String s = ":" + c; if(next != null) s += next.toString(); return s; } public Object clone() { Object o = null; try { o = super.clone(); } catch (CloneNotSupportedException e) {} return o; } public static void main(String[] args) { Snake s = new Snake(5, 'a'); System.out.println("s = " + s); Snake s2 = (Snake)s.clone(); System.out.println("s2 = " + s2); s.increment(); System.out.println( "after s.increment, s2 = " + s2); } } ///:~
  A Snake is made up of a bunch of segments, each of type Snake. Thus, it’s. The output is:
  s = :a:b:c:d:e s2 = :a:b:c:d:e after s.increment, s2 = :a:c:d:e:f
  This means that only the first segment is duplicated by Object.clone( ), will be aliased to those of the original object. It’s analogous to the way constructors are called – base-class constructor first, then the next-derived constructor, and so on to the most-derived constructor. The difference is that clone( ) is not a constructor so there’s nothing to make it happen automatically. You must make sure to do it yourself.(); } return o; } } handles: o.depth = (DepthReading)o.depth.clone(); o.temperature = (TemperatureReading)o.temperature.clone(); return o; // Upcasts back to Object } } public class DeepCopy { public static void main(String[] args) { OceanReading reading = new OceanReading(33.9, 100.5); // Now clone it: OceanReading r = (OceanReading)reading.clone(); } } ///:~
  DepthReading and TemperatureReading are quite similar; they both contain only primitives. Therefore, the clone( ) method can be quite simple: it calls super.clone( ) and returns the result. Note that the clone( ) code for both classes is identical.:
  //: AddingClone.java // You must go through a few gyrations to // add cloning to your own class..out.println("Int2 can't clone"); } return o; } } // Once it's cloneable, inheritance // doesn't remove cloneability: class Int3 extends Int2 { private int j; // Automatically duplicated public Int3(int i) { super(i); } } public class AddingClone {();()).increment(); // See if it changed v's elements: System.out.println("v: " + v); System.out.println("v2: " + v2); } } ///:~
  Int3 is inherited from Int2 and a new primitive member int j is added. You might think that you’d need to override clone( ) again to make sure j is copied, but that’s not the case. When Int2’s clone( ) is called as Int3’s clone( ), it calls Object.clone( ), which determines that it’s working with an Int3 and duplicates all the bits in the Int3. As long as you don’t add(); } } } ///:~
  Thing2 and Thing4 contain member objects so that there’s some deep copying going on. It’s interesting to notice that while Serializable classes are easy to set up, there’s much more work going on to duplicate them. Cloning involves a lot of work to set up the class, but the actual duplication of objects is relatively simple. The results really tell the tale. Here is the output from three different runs:
  Duplication via serialization::
  //: HorrorFlick.java // You can insert Cloneability at any // level of inheritance. import java.util.*; class Person {} class Hero extends Person {} class Scientist extends Person implements Cloneable { public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { // this should never happen: // It's Cloneable already! throw new InternalError(); } } }.?
  Well, when Java was seen as the ultimate Internet programming language, things changed. Suddenly, there are security issues, and of course, these issues are dealt with using objects, and you don’t necessarily want anyone to be able to clone your security objects. So what you’re seeing is a lot of patches applied on the original simple and straightforward scheme: clone( ) is now protected in Object. You must override it and implement Cloneable and deal with the exceptions.
  It’s worth noting that you must use the Cloneable interface only if you’re going to call Object’s clone( ), method, since that method checks at run-time to make sure that your class implements Cloneable. But for consistency (and since Cloneable is empty anyway) you should implement it.
  ] won’t compile.
  There are no comments yet. Be the first to comment!