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 :
- when you have a complex object with many attributes it is much simpler to use the copy constructor
- 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
Is There a Newline Constant Defined in Java Like Environment.Newline in C#
Why Does Inputstream#Read() Return an Int and Not a Byte
Set Private Field Value with Reflection
In Java, How to Efficiently and Elegantly Stream a Tree Node's Descendants
How to Dynamically Add Items to a Java Array
Count Words in a String Method
How to Make a Deep Copy of Java Arraylist
Sum Values from Specific Field of the Objects in a List
JPA Query Selecting Only Specific Columns Without Using Criteria Query
When Does the JPA Set a @Generatedvalue @Id
Java Executors: How to Set Task Priority
How to Use Yamlpropertiesfactorybean to Load Yaml Files Using Spring Framework 4.1
How to Create Splash Screen with Transparent Background in Javafx
How to Open a Windows Named Pipe from Java
How to Get Just the Parent Directory Name of a Specific File
Escaping Special Characters in Java Regular Expressions
Is There a Method for String Conversion to Title Case
Having a 3Rd Party Jar Included in Maven Shaded Jar Without Adding It to Local Repository