Purpose of clone() method in Object class

clone() is a method in Object class, and can be used to create duplicate object. Since Object class is base class of all classes in Java, clone() method is available in all classes. In case an object need to invoke clone() method, that class need to implement java.lang.Cloneable interface. If clone() method is invoked without implementing interface, an exception CloneNotSupportedException is being thrown, and cloning is not successful.

Clone object
Also note that below is not cloning an object, as only one object exists, but just another reference(obj1) is created, and not the actual object. Hence this cannot be considered as cloning.

Abc obj1 = new Abc();
Abc obj2 = obj1;

Below is an example, which throws CloneNotSupportedException

class Test{
	int i;
	String str;

	public Object clone()
	{
		try
		{
			return super.clone();
		}
		catch(CloneNotSupportedException ce)
		{
			ce.printStackTrace();
			return null;
		}
	}
}

public class Demo {
	public static void main(String args[])
	{
		Test obj = new Test();

		Test obj_clone = (Test)obj.clone();
	}
}

Output:

java.lang.CloneNotSupportedException: Test
	at java.lang.Object.clone(Native Method)
	at Test.clone(Demo.java:10)
	at Demo.main(Demo.java:25)


Below is right way to clone an object. As shown the class(whose objects can be successfully cloned) need to implement Cloneable interface


class Test implements Cloneable{
	int i;
	String str;

	public Object clone()
	{
		try
		{
			return super.clone();
		}
		catch(CloneNotSupportedException ce)
		{
			ce.printStackTrace();
			return null;
		}
	}
}

public class Demo {
	public static void main(String args[])
	{
		Test obj = new Test();

		obj.i = 10;
		obj.str = new String("testing");

		Test obj_clone = (Test)obj.clone();

		System.out.println("i="+obj.i+", string is "+obj_clone.str);
	}
}


Output:
i=10, string is testing
However, there can be side effects of cloning, if not used properly. As known, Cloning of an object is creation of exact binary copy of the object.

Cloneable is Marker or Tagging interface(and do not declare any methods), which just conveys JVM that objects of the Class are eligible for cloning.

You may also like to read:
printStackTrace output to a String
stack and heap storage in Java
purpose of finalize() Method
How to override toString()

printStackTrace output to a String

Below example program shows how to convert output of printStackTrace to a String. As known, normal usage of printStackTrace directly outputs to console. But some times it would be required to collect stack trace into a String, mostly for logging purpose.


Here overloaded method printStackTrace(PrintWriter pw) is used.

import java.io.StringWriter;
import java.io.PrintWriter;

class Xyz{
	public void met1()
	{
		int j = 43,k=0;
		try
		{
		System.out.println("stmt 1");
		int i = j/k;
		System.out.println("stmt 2");
		}
		catch(Exception et)
		{
		//Below lines shows how to convert printStack Trace
		//output into a String
		StringWriter ets = new StringWriter();
		et.printStackTrace(new PrintWriter(ets));
		String str = ets.toString();
		//Now, required stack trace is in str

		System.out.println("Stacktrace as string: "+str);
		}
	}
}

public class Abc {
	public static void main(String args[])
	{
		System.out.println("in main");
		Xyz ox =new Xyz();
		ox.met1();
		System.out.println("exiting main");
	}
}

purpose of printStackTrace

printStackTrace() in Exception class, displays stack of details, from where(File name, class name and line number) the exception has been thrown, and further the methods/classes it has been propagated, and where it has been final caught. Click here to read output of printStackTrace into a String

Below is an example on how to use printStackTrace()

class CException
{
	public void testC() throws ArithmeticException,Exception
	{
		DException de = new DException();
		de.testD();
	}
}

class DException
{
	public void testD() throws ArithmeticException,Exception
	{
		int i,j=25,k=5;
			System.out.println("stmt 1");

			i = j/k;

			if(true)
			{
				throw new Exception("SampleException");
			}
			System.out.println("stmt 2");

	}
}

public class SimpleExcp {

	public static void main(String[] args){
		try
		{
			new CException().testC();

			try //nested try block
			{
				throw new Exception("TestingException");
			}
			catch(Exception te)
			{
				te.printStackTrace();
			}
		}
		catch(ArithmeticException ae)
		{
			System.out.println("--------AExcp:"+ae.getMessage());
			ae.printStackTrace();
		}
		catch(Exception et)
		{
			System.out.println("--------Excp:"+et.getMessage());
			et.printStackTrace();
		}
		finally
		{
			System.out.println("in finally block");
		}


	}

}


_______________________________________________________
Output:
——–Excp:SampleException
in finally block
java.lang.Exception: SampleException
at DException.testD(SimpleExcp.java:21)
at CException.testC(SimpleExcp.java:6)
at SimpleExcp.main(SimpleExcp.java:33)