Knowing about copy constructor in java - java

As we know java does not support call by reference and also it's true that if with copy constructor we use call by value then the copy constructor would call itself recursively infinite times.Then how copy constructor do work in java??
Thanks in advance.

The closest equivalent to a copy constructor in Java is overriding the clone() method of the Object class. The javadocs do a fairly good job at explaining its usage.

if with copy constructor we use call by value
There is no copy constructor built-in to Java. You can create one of your own but this is only used when you explicitly call it. To Java it is just another constructor which has no special meaning.
Java only has primitive and reference variable and when these are copied, no method or constructor is called.
e.g. In this example, it is the reference which is copied, not the object.
Integer i = 5; // A *reference* to an Integer object.
Integer i = j; // A *reference* to the same object.
copy constructor would call itself recursively infinite times.
A common misconception is that Java has Object variable types when it doesn't.

Java copy constructor for any object is a deep copy of this object.
For example,
public Car(String motorShow, double price) {
this.motorShow = motorShow;
this.price = price;
} ^ ordinary constructor for a Car object
//the copy constructor for Car:
public Car(Car other) {
this.motorShow = other.motorShow;
this.price = price;
}
/* Simply in the main class write Car c2 = new Car(c1);
this basically will create a copy of c1 of, and note that changing the attributes of one of the objects won't affect the other since it's a deep copy; unlike this for example:
Car c1 = c2;
here, changing any attribute of c1 or c2 will affect the other, i.e two pointers for the same space or reference in memory */
I hope this helps.

Related

what exactly happen in jvm when i create an object in java?

To my understanding if i am writing
Car a3=new Car()
This statement will create a handle named a3 in jvm stack with all its properties in JVM heap.
IF this is correct i am wondering how call by value works.
So, if i create a method checkMethod(Car c) and call it by saying checkMethod(a3);
suppose our car is
public class Car{
int a=0;
public int getpar(){
return a;
}
}
in checkMethod i try to access a using a3.a = 5; so i changed the value of a3.a
it will show me in the calling class as well as it was pointing to the same fields that jvm created in the heap.
But when i do a3= null; in the calling method and go back again in the method from which i was calling
checkMethod(a3) and try to see this object it is not null?
Why it behaved differently as compared to property of object that is a???
checkMethod(a3);
Pass a copy of a value which is a reference to object instance of Car
Inside method...
a3.a = 5
Using a3, modify object instance of Car which is identified by a3 ( which is a copy of original a3).
a3 = null
Set the reference to null ( copy)
When this happens, only the copy you passed to your method will point to null. But the original a3 still points to your object instance of Car.
Why it behaved differently as compared to property of object that is a?
Because Java is (pure) call by value. You cannot manipulate the value of the parameter within the callee context. You always gets a local copy in the calling context.
On method calls, Java passes a copy of the reference.
So when setting a3 to null, it only set its copy of the reference to null and the other copies that are stored else where.
The whole trick is this: Java passes references by value :)

Java equivalent of C++ copy assignment operator

I'm trying to understand this operator function written in C++ and convert it to Java.
Class& Class::operator=(const Class& In) {
properties = In.properties;
return *this;
}
Does this simply copy instance and properties of a class object? For which I've already written something:
public static Class copy(Class obj) {
//returns new instance of Class individual
Class copy = new Class(obj.row_num, obj.col_num, obj.input_length, obj.output_length, obj.max_arity, obj.function_length, obj.levels_back);
copy.genes = obj.genes.clone();
return copy;
}
Am I on the correct track? Many thanks for your help.
Ampersand & designates a reference in C++. It is needed to provide the behavior similar to what Java objects provide "out of the box", because Java manages objects through references.
There is no copying going on in C++ when a reference is passed. In fact, avoiding copying is a major reason for using const references as function parameters.
The code that you show does not perform copying either: it changes its state based on the value being "assigned". The closest way of modeling this in Java would be providing an assign(Class other) method that changes the current state to match that of the object passed in:
Class assign(Class other) {
this.properties = other.properties;
return this;
}
You will need to use this method in place of C++'s assignment, like this:
Class clOne(args1);
Class clTwo(args2);
clOne = clTwo; // Using the assignment operator
becomes this:
Class clOne = new Class(args1);
Class clTwo = new Class(args2);
clOne.assign(clTwo); // Using the assignment method instead of the operator
You're pretty much on the right track. The copy assignment operator in C++ is used when directly assigning (copying) from one object to another. As Java objects are only accessible via references, such assignments are meaningless. To match the C++ semantics exactly, the Java equivalent would be:
public Class copy(Class obj) {
row_num = obj.row_num;
col_num = obj.col_num;
// etc., etc.
genes = obj.genes.clone();
return this;
}
Am I on the correct track?
Kind of. But not quite. C++ distinguishes between reassigning an existing object and creating a new one.
Java doesn’t. You cannot reassign to an existing object in Java1 (but you can of course reassign a reference). In Java, in order to copy an object (rather than assign a reference to it), you would usually use a copying constructor:
Class(Class other) {
// Copy members of `other` into `this`.
}
And then use it as follows:
Class x = new Class(something here);
Class y = new Class(x); // copy
In particular, this is what all the Java containers implement. I would not rely on clone. First of all, clone should only be used if the class implements the tag interface Cloneable. Second of all, clone’s design is arguably broken and its use is not recommended.
1 Well you could of course reassign the members of an object (unless they are final), and you could mimic C++’s copy assignment operator by providing a method assign to do that. However, this isn’t the conventional way of doing things in Java (although it might have its place in some exceptional instances).

How do I do a Java-deep copy of an object?

I have a class (Literal). I need to be able to keep an intact Literal instance in memory throughout my application, and have a copy of it which I can alter. I have used two ways to do this:
class Literal implements Cloneable and override Object.clone() method.
Factory constructor:
public Literal(Literal lit){
this = lit;
}
In both cases copying doesn't work. Every change I make to the copy, changes the original. Does anybody have any idea what I'm doing wrong?
since Literal is not a integral type, variables of type Literal holds a reference to the actual value, so this = lit just copies the reference, so your behavior.
You must copy all the member fields recursively to do a "real" copy.
This article has been linked in the accepted answer to the question linked by Umesh in his comment, and I think it clears the conceptual problems you're hitting with your problem.
If you are going to use copy-constructor, then you will need to make a deep copy of every mutable member variable.
Say your Literal has member variables like this:
private String[] args;
private String s;
Then your copy-constructor would need to do something like this
public Literal(Literal l) {
// have to deep copy the array, otherwise both instances are sharing the reference
this.args = Arrays.copyOf(l.args, l.args.length);
// safe to just copy the reference, String is immutable
this.s = l.s;
}

Why do we use the clone() method in Java?

Why do we use the clone() method in Java? (Please give the answer in respect of memory constraint.) Will that reduce memory usage? If yes, then how? Will that reduce the effect of memory leak?
Apart from do not use clone, implement a copy constructor, you asked about memory constraints.
The idea of cloning is to create an exact duplicate of the cloned object. So in worst case, you use twice the amount of memory afterwards. Practically - a bit less, because Strings are often interned and will (usually) not be cloned. Even though it's up to the implementor of the clone method/copy constructor.
Here's a short example of a class with a copy constructor:
public class Sheep {
private String name;
private Fur fur;
private Eye[2] eyes;
//...
// the copy constructor
public Sheep(Sheep sheep) {
// String already has a copy constructor ;)
this.name = new String(sheep.name);
// assuming Fur and Eye have copy constructors, necessary for proper cloning
this.fur = new Fur(sheep.fur);
this.eyes = new Eye[2];
for (int i = 0; i < 2; i++)
eyes[i] = new Eye(sheep.eyes[i]);
}
}
Usage:
Sheep dolly = getDolly(); // some magic to get a sheep
Sheep dollyClone = new Sheep(dolly);
We should not use it. It is a broken and obsolete idiom, which should be avoided in new code. Better use a copy constructor instead whenever you can.
The clone() copies the values of an object to another.
clone() method saves the extra processing task for creating the exact copy of an object.
As you can see in the below example, both reference variables have the same value.
class Student18 implements Cloneable {
int rollno;
String name;
Student18(int rollno, String name) {
this.rollno = rollno;
this.name = name;
}
public static void main(String args[]) {
try {
Student18 s1 = new Student18(101, "amit");
Student18 s2 = (Student18) s1.clone();
System.out.println(s1.rollno + " " + s1.name);
System.out.println(s2.rollno + " " + s2.name);
} catch (CloneNotSupportedException c) {
}
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Output :
101 amit
101 amit
If we create another object by new keyword and assign the values of another object to this one, it will require a lot of processing on this object. So to save the extra processing task we use clone() method.
if we need to use many object having the same data, then don't create objects using new keyword. use clone method to create that object, because operation of creating object with clone method is faster than using new keyword.
Making a copy of an object seems at first to be a straight forward task:
Simply copy the values of all the properties into another instance of the same class.
But what about the variables that are references to other objects? Copies of these reference values mean they will point to the same objects as the first class.
But maybe that is not what we want. Perhaps we want all the objects referenced by the copy to be independent copies as well.
These two types of object copies are called:
shallow copy - exact bit copy of all the attributes of the original object
deep copy - primitives are copied exactly but objects referenced are copied rather than the references themselves.
The Object class, which is inherited by all Java classes, includes the clone() method that will make exact bit copies of all the properties.
However, clone() is a protected method. So a given object can not be cloned by instances of any classes outside the package (unless they are subclasses of that object's class). This allows the class designer to specify explicitly what kind of clones (shallow or deep) to make.
Java requires classes that want to override the clone() method, to implement the cloneable interface. The clone() method must be made public as well so as to override the access restrictions.
For example, the HashTable class implements cloneable. Its clone() method makes a shallow copy so the keys and values of the copied HashTable will reference the same objects as the original.
Many core Java classes, however, do not implement cloneable. If the clone() method is invoked for such classes, a CloneNotSupportedException will result.
see clone constraints
in few words it is used to copy the objects instead the references, it increase the memory usage.
We should avoid using clone()
Here is good example

Function didn't change the value - JAVA 6 SE

I can't understand why the overloaded function 'increase' does not change Integer but does change Point.
The propuse of 'Integer' class is to wrap int so it will be a reference Type.
import java.awt.Point;
public class test2 {
public static void main(String[] args) {
///1
Integer i = new Integer(0);
increase(i);
System.out.println(i);
///2
Point p = new Point(0,0);
increase(p);
System.out.println(p);
}
public static void increase(Integer i){
i = 1;
}
public static void increase(Point p){
p.setLocation(1, 1);
}
}
the output is :
0
java.awt.Point[x=1,y=1]
Also, is their a simple way to pass a variable to a function by reference in Java?
Integer class is an immutable class, that means its content can't be changed after it's created.
Also, Java is pass-by-value so the variable i is passed by value, and the fact that it changes inside the function has no effect on the caller.
Read here: http://en.wikipedia.org/wiki/Immutable_object for more information on immutable objects.
The simple answer is that Java uses pass by value, not pass by reference.
In the Point case, the method is changing a field of the point object whose reference was passed into the method.
In the Integer case, the method is simply assigning a new value to the local variable i. This does not update the variable i in the calling method, because Java uses pass by reference.
The other issue is that Integer has no setValue methods because it is immutable. If you want to do the equivalent of what the Point version of the method is doing, you will have to define an IntegerHolder class that has both a getter and a setter, together with methods such as increase, that your application needs. (Alternatively, find such a class in a 3rd party library.)
Integer objects are immutable, i.e. you can't change them. If you could, the syntax would be like
i.setValue(1);
If you want to pass a non-object by reference, you can either wrap it in an array of length 1 or (better) create a trivial wrapper. However, there is little reason to do so - don't port your code from C 1:1. Usually, you should have a semantically loaded object, like an Account on which you can call the increase and decrease (or maybe just setBalance) methods.
In this function:
public static void increase(Integer i){
i = 1;
}
autoboxing makes this equivalent to:
public static void increase(Integer i){
i = new Integer(1);
}
i.e. it changes the reference that i contains, not the value that it contains. The Integer object is itself immutable, there's actually no way to change the value of one after it has been created.
Since that reference is a local variable, any changes to it will not affect the variable that was passed in.
When you write i = 1, you are changing the i parameter to point to a new boxed Integer instance.
The original Integer instance that you passed to the function is not—and cannot be—changed—Integers are immutable
Answer here: http://www.javaworld.com/javaworld/javaqa/2000-06/01-qa-0602-immutable.html
This reference could be useful: http://javadude.com/articles/passbyvalue.htm
If you wanted the two methods to be equivalent, the second one would look like this:
public static void increase(Point p){
p = new Point(1, 1);
}
And then you would see that it outputs the original point here, too.
There is no pass a variable to a function by reference in Java.
You can simulate it by passing an object which contains the variable (like you did in your increase(Point) method) - you'll have to be sure to assign to the variable, though, not to the object containing the variable.
As said before, there are several "mutable wrappers" around (for example org.omg.CORBA.IntHolder and java.util.concurrent.AtomicInteger in the standard API), but it is not difficult to create your own, and in most cases it would be better to use a sensible "Business object" like an "Account" instead.

Categories

Resources