Architecture & Design Object Integrity & Security: Duplicating Objects

Object Integrity & Security: Duplicating Objects

Introduction

This series, The Object-Oriented Thought Process, is intended for someone just learning an object-oriented language and who wants to understand the basic concepts before jumping into the code, or someone who wants to understand the infrastructure behind an object-oriented language he or she is already using. These concepts are part of the foundation that any programmer will need to make the paradigm shift from procedural programming to object-oriented programming.

Using the clone() method does take a bit of work. In Listing 03, you add the line of code to clone the object (see the line in red).

// Class Duplicate
public class Duplicate {

   public static void main(String[] args) {

      Dog fido = new Dog("fido", "retriever");

      Dog spot;

      spot = fido.clone();

      System.out.println("name = " + fido.getName());
      System.out.println("name = " + spot.getName());


   }
}

Listing 03: The Duplicate Class

However, when you compile this code, you run into some tricky issues. As you can see in Figure 03, the coding involved is not totally straightforward. Specifically, you have two issues that you have to deal with. The first is the fact that the clone() method in the object class is defined as protected. The second comes into play because the compiler complains that the cloning procedure is dealing with incompatible types.

Figure 03: Attempting to Clone an Object

The first issue can be dealt with by overriding the clone() method in the Dog class itself. In fact, the clone() method is meant as a standard interface and not a complete solution to object duplication. Thus, like constructors, you probably want to create your own version of the clone() method.

In Listing 04, you add the code for the localized clone() method override in red. You will explore this code in much more detail in the next column; however, pay special attention to the fact that the Dog class implements the Clonable interface and that you must make provisions to catch the CloneNotSupportedException exception.

// Class Dog
class Dog implements Cloneable {

   String name;
   String breed;

   public Dog(String n, String b) {

      name  = n;
      breed = b;

   }

   public Object clone() {
      try {
         return super.clone();
      } catch (CloneNotSupportedException e) {
         throw new InternalError(e.toString());
      }
   }

   public String getName() {

      return name;

   }

   public void setName(String n) {

      name = n;

   }

   public String getBreed() {

      return breed;

   }

}

Listing 04: The Dog Class with the clone() Override

The second issue deals with casting. When the clone() method returns the object, the object in this case is of type Dog. Thus, you need to cast the return to the type Dog. This is illustrated in Listing 05.

// Class Duplicate
public class Duplicate {

   public static void main(String[] args) {

      Dog fido = new Dog("fido", "retriever");

      Dog spot;

      spot = (Dog) fido.clone();

      System.out.println("name = " + fido.getName());
      System.out.println("name = " + spot.getName());


   }
}

Listing 05: The Duplicate Class with the clone() method

With both of the changes in place, you can run the code that produces the output in Figure 4.

Figure 1.Cloning an Object

Now, this output looks identical to the output in Figure 02, without cloning the object—and this is in fact the case. The primary difference, and the important difference, is that there are now two totally separate objects. As you did with the previous two examples, you can represent this graphically to illustrate how the objects are represented in memory. Diagram 03 shows that in this case you not only have two references, you also have two objects.

Diagram 03: An Object with Two References to Two Objects.

When you look at Diagram 03, you may notice one inconsistency; the spot object still has the name defined as fido. In fact, the output in Figure 04 confirms this. This makes sense because you did clone the object, and this implies that all of the information is duplicated. Given this fact, how do you prove that the objects are indeed separate? Change the value of one, but not the other, as seen in Listing 06. Logically, you need to change the name of the spot object to “spot”. You use the setName() method that you added earlier.

// Class Duplicate
public class Duplicate {

   public static void main(String[] args) {

      Dog fido = new Dog("fido", "retriever");

      Dog spot;

      spot = (Dog) fido.clone();

      spot.setName("Spot");

      System.out.println("name = " + fido.getName());
      System.out.println("name = " + spot.getName());


   }
}

Listing 06: Change the name for the spot reference

Figure 05: Cloning an Object

At this point, the graphical representation is in a logical state, the fido references and object with the name of fido, and the spot references and object with the name of spot, as seen in Diagram 04.

Diagram 04: An Object with Two References to Two Objects.

Conclusion

At this point, you have covered some of the basic mechanics of duplicating objects. As you can see, duplicating objects is not really as simple as it might seem. Copying primitives, such as a double, can be accomplished by a simple variable declaration and an assignment as seen below.

// Code to create a duplicate double data type

double a = 5;
double b = 0;

b = a;

This works because the double represents only a single address location (however many bytes that a double consumes). Because objects potentially contain other primitives and other objects, the number of address references is not limited to a single address reference. With objects, duplication is much more involved. You will explore more of these details in future articles.

This is where the concept of shallow and deep copies comes into play. You will take a look at these concepts as you continue to explore the cloning process.

References

About the Author

Matt Weisfeld is a faculty member at Cuyahoga Community College (Tri-C) in Cleveland, Ohio. Matt is a member of the Information Technology department, teaching programming languages such as C++, Java, C#, and .NET as well as various web technologies. Prior to joining Tri-C, Matt spent 20 years in the information technology industry, gaining experience in software development, project management, business development, corporate training, and part-time teaching. Matt holds an MS in computer science and an MBA in project management. Besides The Object-Oriented Thought Process, which is now in its second edition, Matt has published two other computer books, and more than a dozen articles in magazines and journals such as Dr. Dobb’s Journal, The C/C++ Users Journal, Software Development Magazine, Java Report, and the international journal Project Management. Matt has presented at conferences throughout the United States and Canada.

Latest Posts

Related Stories