Why Do We Need Copy Constructor and When Should We Use Copy Constructor in Java

Why do we need copy constructor and when should we use copy constructor in java

There are 2 good reasons for using a copy constructor instead of the constructor passing all parameters :

  1. when you have a complex object with many attributes it is much simpler to use the copy constructor
  2. if you add an attribute to your class, you just change the copy constructor to take this new attribute into account instead of changing every occurence of the other constructor

Why String class has copy constructor?

The main reason to copy a string is to "trim the baggage", that is to trim the underlying char array to only what is necessary.

The underlying char array can mainly be too big because when you create a string by calling substring, the char array can be shared between the new string instance and the source string instance; an offset points to the first character and the length is included.

The expression I use, "trim the baggage", is taken from the source code of String copying constructor :

  164       public String(String original) {
165 int size = original.count;
166 char[] originalValue = original.value;
167 char[] v;
168 if (originalValue.length > size) {
169 // The array representing the String is bigger than the new
170 // String itself. Perhaps this constructor is being called
171 // in order to trim the baggage, so make a copy of the array.
172 int off = original.offset;
173 v = Arrays.copyOfRange(originalValue, off, off+size);
174 } else {
175 // The array representing the String is the same
176 // size as the String, so no point in making a copy.
177 v = originalValue;
178 }
179 this.offset = 0;
180 this.count = size;
181 this.value = v;

This is something many developers forget and is important because a small string may prevent the garbaging of a bigger char array. See this related question where I already pointed this : Java not garbage collecting memory. Many developers consider than the decision of Java designers to use this old optimization trick that was familiar to C coders did, in fact, more harm than good. Many of us know it because we were bitten by it and did have to look into Sun's source code to understand what happened...

As Marko points out (see comments below), in OpenJDK, starting from java 7 Update 6, substring doesn't share the char array anymore and the String(String) constructor is, thus, useless. But it's still fast (even faster in fact) and as this change hadn't been propagated to all VM (and probably not all your customers) I'd recommend to keep this best-practice to use new String(substring) when the old behavior was justifying it.

Why doesn't Java have a copy constructor?

Java does. They're just not called implicitly like they are in C++ and I suspect that's your real question.

Firstly, a copy constructor is nothing more than:

public class Blah {
private int foo;

public Blah() { } // public no-args constructor
public Blah(Blah b) { foo = b.foo; } // copy constructor
}

Now C++ will implicitly call the copy constructor with a statement like this:

Blah b2 = b1;

Cloning/copying in that instance simply makes no sense in Java because all b1 and b2 are references and not value objects like they are in C++. In C++ that statement makes a copy of the object's state. In Java it simply copies the reference. The object's state is not copied so implicitly calling the copy constructor makes no sense.

And that's all there is to it really.

Clone() vs Copy constructor- which is recommended in java

Clone is broken, so dont use it.

THE CLONE METHOD of the Object class
is a somewhat magical method that does
what no pure Java method could ever
do: It produces an identical copy of
its object. It has been present in the
primordial Object superclass since the
Beta-release days of the Java
compiler*; and it, like all ancient
magic, requires the appropriate
incantation to prevent the spell from
unexpectedly backfiring

Prefer a method that copies the object

Foo copyFoo (Foo foo){
Foo f = new Foo();
//for all properties in FOo
f.set(foo.get());
return f;
}

Read more
http://adtmag.com/articles/2000/01/18/effective-javaeffective-cloning.aspx

difference between Java and C++ copy constructor

Java has no specific linguistic support for copy constructors. Rather you just code the state copying by hand in the constructor; e.g.

public class Person {
private String firstName;
private String lastName;

public Person(Person other) {
this.firstName = other.firstName;
this.lastName = other.lastName;
}
...
}

I would like to understand the Java equivalent of the logic to execute rule of three (copy constructor, destructor, assignment operator) from the compiler side of the story.

The copy constructor is as above. Is really just a (simple) design pattern.

Java doesn't provide an equivalent to C++ assignment operator loading. Java supports assignment of primitive types and reference types, but not assignment of objects in the same way that C++ does. It is unusual for special actions are required when assigning a value in Java. And in the cases where you need to do this, it is customary to put the logic into a setter method.

Java supports finalize methods, that are similar in some respects to C++ destructors. The primary differences are that finalize methods are operations on objects not reference variables, and they are typically called a long time after the object's last reference has gone out of scope.

However, you rarely need to use finalize methods:

  • Java is a fully garbage collected language, and the best strategy for memory management is to just let the GC take care of it.

  • Other resources are best managed using "try / finally" or "try with resources".

AFAIK, the only sound use-case for finalize methods is for cleaning up resources that have been lost accidentally; e.g. because someone forgot to "close" them using the recommended mechanisms.

Why should the copy constructor accept its parameter by reference in C++?

Because if it's not by reference, it's by value. To do that you make a copy, and to do that you call the copy constructor. But to do that, we need to make a new value, so we call the copy constructor, and so on...

(You would have infinite recursion because "to make a copy, you need to make a copy".)



Related Topics



Leave a reply



Submit