The clone method in C # (or in java) uses the new operator inside?

It was actually an interview question, about different ways of creating class instances. new and reflected are well known. But clone () also creates objects. But does he use an internally new keyword to create it? This was set in the context of C #, but would also like to know about java.

+4
source share
6 answers

Clone() in C # is implemented by implementing the ICloneable interface. How you do this is completely up to you.

For instance,

  • Immutable objects, such as String and RuntimeType , simply return this (that is, themselves).
  • A few standard Clone calls (i.e. System.Array , System.Delegate return Object.MemberwiseClone() ), which calls the CLR call to create a shallow copy. I believe this is similar to new() (it will create new links, etc ..), but I don't believe it (although I don't have an assembly to confirm), it will call the constructor.
  • Other objects tend to implement their own Clone() procedure.

Example Clone() method from System.Version

 public object Clone() { Version version = new Version(); version._Major = this._Major; version._Minor = this._Minor; version._Build = this._Build; version._Revision = this._Revision; return version; } 
+3
source

In Java, when calling clone() convention is that the returned object must be obtained by calling super.clone() . In the end, it comes to Object clone() . At this point, the behavior is determined by the Clonable interface: if the class implements Clonable , the clone() method of Object returns a copy of the object field by field ; otherwise, a CloneNotSupportedException is CloneNotSupportedException . Thus, clone() creates an object without calling the constructor, you get a shallow copy of the object.

As a note to Java clone , it is known that it was damaged , and Joshua Bloch recommends providing a constructor or a copy of the factory . This is discussed in Effective Java 2nd Edition, Clause 11: Reasonably reject a clone .

+3
source

Typically, Clone implementations would use the MemberwiseClone protected method to create the base object, and then, if necessary, set up the fields (for example, a deep copy of the list instead of both instances referring to the same one).

There is nothing that says they should do this, although they could call the constructor to create the object, and then set the fields if necessary.

Inside MemberwiseClone (I think I'm not sure about that) is just a direct transcription of the memory that the object occupies, and is in no way associated with the constructor.

0
source

For Java, the answer is no. The documentation is very specific regarding the algorithm:

this method creates a new instance of the class of this object and initializes all its fields with the exact contents of the corresponding fields of this object, as if it were assigned; the contents of the fields are not cloned per se. Thus, this method performs a “shallow copy” of this object, and not a “deep copy” operation.

http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/Object.html#clone ()

You can also easily test this in practice.

0
source

OK, so the consensus is that since the new one includes the constructor, and the clone does not include the call to the constructor (unless we come up with our implementation of the clone), the clone does not use the new internal one.

0
source

For C #, it is very simple to check which object.MemberwiseClone does in terms of constructors:

 class Program { class A : ICloneable { public int X = 2; public A() { Console.WriteLine("hiya"); X = 1; } public object Clone() { A a = MemberwiseClone() as A; return a; } } static void Main(string[] args) { A a = new A(); aX = 3; A b = a.Clone() as A; } } 

Place a breakpoint in the constructor. It is called once for the above program. And if you think about it, Clone in the base class cannot call the constructor:

  • What is he going to build? This can reflect and get the maximum derived type.
  • But what if this type does not have a constructor publicly accessible without parameters?
  • Whether it can call a private or protected constructor, and expect the object to be initialized correctly.

The standard implementation of MemberWiseClone should depend on the initialization of the lower level type, and not on the design. An alternative would be difficult to implement, difficult to understand and find the source of errors.

0
source

Source: https://habr.com/ru/post/1315151/


All Articles