class

Avoid side-effects with Object.clone

In this example we shall show you how to avoid side-effects when using Object.clone. To avoid side-effects when using Object.clone we have performed the following steps:

  • We have created a class, Enemy, that has a method, void mungeFunc(SideEffects sdf), where it gets an object of SideEffects class and changes its fields’ values.
  • SideEffects class implements the Cloneable interface to indicate to the java.lang.Object.clone() method that it is legal to make a field-for-field copy of instances of that class.
  • The class has a public Date field, that will be cloned and a volatile int field, that cannot be cloned. It also has a constructor using its fields.
  • SideEffects also has a method, void process(), that creates a new Enemy instance, calls mungFunc() method of Enemy class, using the clone() method of SideEffects and then calls mungFunc() again, using the SideEffects object where the method is run.
  • We create a new instance of SideEffects and call its process() method.
  • The date and year fields of SideEffects have the values they get when a new instance of SideEffects is created.
  • When mungFunc() is called using the clone object of SideEffects, although the date field is cloned, since the year field is volatile it is not cloned, so it cannot be changed.
  • When mungFunc() is called using the original object of SideEffects, both fields are changed by the mungFunc() method,

as described in the code snippet below.

package com.javacodegeeks.snippets.core;


import java.util.Date;

/**
 * Simple demo of avoiding side-effects by using Object.clone() to duplicate an
 * object before passing it to your enemy's methods. Cloneable is a "marker"
 * interface: it has no methods, but is tested for by Object.clone.
 *
 * If you implement it, you tell Object.clone that your data is stable enough
 * that field-by-field copy is OK.
 */

class Enemy {

    public void mungeFunc(SideEffects sdf) {

  System.out.println("Object is " + sdf);

  sdf.year = 0;

  sdf.date.setYear(71);    // Ignore deprecation warnings
    }
}

public class SideEffects implements Cloneable {

    /**
     * When we clone a "SideEffects", this REFERENCE gets cloned
     */
    public Date date;
    /**
     * When we clone a "SideEffects", this integer does NOT get cloned
     */
    volatile int year;

    public static void main(String[] argv) throws CloneNotSupportedException {

  new SideEffects().process();
    }

    SideEffects() {

  date = new Date();  // today

  year = date.getYear();
    }

    public void process() throws CloneNotSupportedException {

  

  Enemy enemy = new Enemy();

  System.out.println("We have seen the enemy, and he is " + enemy);

  System.out.println("Today is " + date );

  System.out.println("And the year is " + year);

  enemy.mungeFunc((SideEffects) this.clone());

  System.out.println("Why, I believe it is now " + date);

  if (year == 0) // should not happen!!

  {


System.out.println("** PANIC IN YEAR ZERO **");

  }

  System.out.println("But wait, the year is still " + year);

  enemy.mungeFunc(this);

  System.out.println("Now I'm certain that it's " + date);

  System.out.println("Now the year is  " + year);
    }
}

Output:

We have seen the enemy, and he is methodoverloading.Enemy@33e92e10
Today is Fri Jun 22 16:53:40 EEST 2012
And the year is 112
Object is methodoverloading.SideEffects@7a5d5033
Why, I believe it is now Tue Jun 22 16:53:40 EEST 1971
But wait, the year is still 112
Object is methodoverloading.SideEffects@43c8308
Now I'm certain that it's Tue Jun 22 16:53:40 EEST 1971
Now the year is  0

 
This was an example of how to avoid side-effects when using Object.clone in Java.

Byron Kiourtzoglou

Byron is a master software engineer working in the IT and Telecom domains. He is an applications developer in a wide variety of applications/services. He is currently acting as the team leader and technical architect for a proprietary service creation and integration platform for both the IT and Telecom industries in addition to a in-house big data real-time analytics solution. He is always fascinated by SOA, middleware services and mobile development. Byron is co-founder and Executive Editor at Java Code Geeks.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button