大橙子网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
Now think about what happens if we run the same basic code but use a reference type instead of a primitive type:
网站建设哪家好,找创新互联公司!专注于网页设计、网站建设、微信开发、成都微信小程序、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了上海免费建站欢迎大家使用!
Point p = new Point(1.0, 2.0); Point q = p;
After this code runs, the variable q holds a copy of the reference held in the variable p. There is still only one copy of the Point object in the VM, but there are now two copies of the reference to that object. This has some important implications. Suppose the two previous lines of code are followed by this code:
System.out.println(p.x); // Print out the X coordinate of p: 1.0 q.x = 13.0; // Now change the X coordinate of q System.out.println(p.x); // Print out p.x again; this time it is 13.0
Since the variables p and q hold references to the same object, either variable can be used to make changes to the object, and those changes are visible through the other variable as well.
[@more@]A similar difference in behavior between primitive types and reference types occurs when arguments are passed to methods. Consider the following method:
void changePrimitive(int x) { while(x > 0) System.out.println(x--); }
When this method is invoked, the method is given a copy of the argument used to invoke the method in the parameter x. The code in the method uses x as a loop counter and decrements it to zero. Since x is a primitive type, the method has its own private copy of this value, so this is a perfectly reasonable thing to do.
On the other hand, consider what happens if we modify the method so that the parameter is a reference type:
void changeReference(Point p) { while(p.x > 0) System.out.println(p.x--); }
When this method is invoked, it is passed a private copy of a reference to a Point object and can use this reference to change the Point object. Consider the following:
Point q = new Point(3.0, 4.5); // A point with an X coordinate of 3 changeReference(q); // Prints 3,2,1 and modifies the Point System.out.println(q.x); // The X coordinate of q is now 0!
When the changeReference() method is invoked, it is passed a copy of the reference held in variable q. Now both the variable q and the method parameter p hold references to the same object. The method can use its reference to change the contents of the object. Note, however, that it cannot change the contents of the variable q. In other words, the method can change the Point object beyond recognition, but it cannot change the fact that the variable q refers to that object.
The title of this section is "Copying Objects and Arrays," but, so far, we've only seen copies of references to objects and arrays, not copies of the objects and arrays themselves. To make an actual copy of an object or an array, you must use the special clone() method (inherited by all objects from java.lang.Object):
Point p = new Point(1,2); // p refers to one object Point q = (Point) p.clone(); // q refers to a copy of that object q.y = 42; // Modify the copied object, but not the original int[] data = {1,2,3,4,5}; // An array int[] copy = (int[]) data.clone(); // A copy of the array
Note that a cast is necessary to coerce the return value of the clone() method to the correct type. The reason for this will become clear later in this chapter. There are a couple of points you should be aware of when using clone(). First, not all objects can be cloned. Java only allows an object to be cloned if the object's class has explicitly declared itself to be cloneable by implementing the Cloneable interface.The definition of Point that we showed earlier does not actually implement this interface, so our Point type, as implemented, is not cloneable. Note, however, that arrays are always cloneable. If you call the clone() method for a non-cloneable object, it throws a CloneNotSupportedException, so when you use the clone() method, you may want to use it within a try block to catch this exception.
The second thing you need to understand about clone() is that, by default, it is implemented to create a shallow copy of an object or array. The copied object or array contains copies of all the primitive values and references in the original object or array. In other words, any references in the object or array are copied, not cloned; clone() does not recursively make copies of the objects or arrays referred to by those references. A class may need to override this shallow copy behavior by defining its own version of the clone() method that explicitly performs a deeper copy where needed. To understand the shallow copy behavior of clone(), consider cloning a two-dimensional array of arrays: