Over a million developers have joined DZone.

A Few Notes About Java clone() Method

· Java Zone

Learn more about the advantages of moving from a monolithic to microservices architecture.  Brought to you in partnership with IBM.

Did you know you can create new Java instance without constructor? That's right, and this feature is brought to you by the Java clone() method. I personally don't like to use it much because it has many pitfalls, and it feels very broken in many ways. You probably can write better "clone" by using copy constructor or a static copy factory methods.

Anyrate, here is a unit test that highlights few notes I have gathered about Java clone. Look for the "Note" comments below.

package atest;

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

public class CloneTest {
    public void testFooClone() throws Exception {
        Foo a = new Foo();
        Foo b = a.clone();

        assertThat(a != b, is(true));
        assertThat(a.constructorCallsCount, is(1));
        assertThat(a.name, is("foo"));
        assertThat(b.constructorCallsCount, is(1)); // Note1: Wow, a new instance without calling constructor!
        assertThat(b.name, is("foo"));

        a.name = "fooX";
        assertThat(a.name, is("fooX"));
        assertThat(b.name, is("foo"));

        Foo2 c = new Foo2();
        Foo2 d = c.clone();


        assertThat(c != d, is(true));
        assertThat(c.constructorCallsCount, is(2));
        assertThat(c.name, is("foo"));
        assertThat(d.constructorCallsCount, is(2));
        assertThat(d.name, is("foo"));

        assertThat(c.ids, hasItems("A"));
        assertThat(c.ids.size(), is(1));
        assertThat(d.ids, hasItems("a", "b"));
        assertThat(d.ids.size(), is(2));

    /** A simple clone examples with simple type fields. */
    public static class Foo implements Cloneable {
        static int constructorCallsCount = 0;
        String name = "foo";
        public Foo() {
        public Foo clone() {
            // Note2: Catch checked exception here so client or subclass doesn't need to.
            Foo result = null;
            try {
                result = (Foo)super.clone();
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException("Unable to clone.", e);
            return result;

    /** A clone example that needs to fix field afterward super.clone(). */
    public static class Foo2 extends Foo {
        List<String> ids = new ArrayList();
        public Foo2 clone() {
            Foo2 result = (Foo2)super.clone(); // Note3: Some how, super clone will auto return the correct type!
            result.ids = new ArrayList(ids);   // Note4: need to fix non-simple field.
            return result;

From Idea to Application gives you the architecture to quickly build, manage and run a range of applications (web, mobile, big data, new smart devices, etc.) on an open-standard, cloud-based platform. See why developers are using IBM Bluemix. Brought to you in partnership with IBM.


Published at DZone with permission of Zemian Deng, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}