Effective Java Item 11: Override clone Judiciously

眉间皱痕 提交于 2019-12-06 01:26:49

By calling s1.setMarks(new int[]{10, 10, 10}); you're creating a completely new array and write its reference to the variable marks of s1. So s1 and s2 refer to two different arrays.

If you would have this method:

public void setMark(int mark, int pos) {
    marks[pos] = mark;
}

in the class Student and perform following code:

System.out.println("Updating the array element in Original...");
s1.setMark(999, 0);
System.out.println("S1 : " + s1);
System.out.println("S2 : " + s2);

then you will see, that this affects s2 too:

Updating the array elements in Original...
S1 : Student - Name : Mohit Age : 30 Marks : [999, 70, 80]
S2 : Student - Name : Rohit Age : 29 Marks : [999, 70, 80]

(don't forget to comment the line s2.setMarks(new int[]{10, 29, 30});, as well, because this line also creates a new array reference and removes the (array) binding between s1 and s2)

This behavior could be described with a "real world example":

Image you and a friend are holding a rope, with one person on each end. This rope represents the Array you're both referring to. If your friend pulls that rope (changing a value in that array), you'll notice that. And if you pull that rope, your friend will notice that, too.

By calling s1.setMarks(new int[]{...}); your friend gets a new rope and he will drop the first one for it. If he pulls that rope, you won't notice that, because you two have different ones. By calling s2.setMarks(new int[]{...}); you will get a new rope and drop the first one, as well. This is the signal for the third friend, called Garbage Collector, to take that rope and dump it, because no one is using it anymore. But this friend is kind of lazy, so there is no guarantee that he will do that immediately.

A variable of type int[] may be used to encapsulate any of four different things:

  1. The contents of an array which will never be modified.

  2. The contents of an array which might be modified, and to which no references exist that the owner of the variable doesn't know about.

  3. The identity of an array which might be modified, and which is owned by someone else.

  4. The identity of an array which might be modified, and which is owned by the owner of the variable, but to which other references may exist.

A clone() method doesn't need to clone arrays of the first type, but aside from a slight performance cost cloning such arrays is likely to be harmless. A clone() method must, however, clone arrays of the second type and refrain from cloning arrays of the third type. Objects that own arrays of the fourth type should generally not implement clone().

It's not clear whether you really want your code to consider the array to be of the first type or the third; in neither case is it necessary for your clone method to clone the array. The second pattern is the most common when using array-type variables, but your particular usage case doesn't fit it.

For every array-type variable, identify which of the four cases applies and it will be clear how you should proceed with clone. Note that you can't classify an array into one of the four types, your code is probably broken, and you should fix it before worrying about clone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!