从数组的不同赋值来看Java中的指针引用与对象的clone()方法
最近在看Arrays.sort()方法如何使用,突然发现,保存原始的数组变成了一件困难事情。
问题出在,无法准确的判断Java中的引用和赋值。
来看下面一个例子:
public static void main(String[] args) { int[] nums1 = {0,2,3,10,8,11,21}; int[] nums2 = {}; System.out.print("Nums1 = "); for (int i = 0; i < nums1.length; i++) { System.out.print(" "+nums1[i]); } System.out.println(); nums2 = Arrays.copyOf(nums1, nums1.length); // 这个选择,会新建nums2的地址空间指向新的数组空间地址。, // nums2 = nums1; // 这个选择,将会把nums2的地址指针,指向nums1,导致对nums1 排序也会对nums2排序, Arrays.sort(nums1); System.out.print("Nums2 = "); for (int i = 0; i < nums1.length; i++) { System.out.print(" "+nums2[i]); } System.out.println(); }
打印输出结果:
Nums1 = 0 2 3 10 8 11 21
Nums2 = 0 2 3 8 10 11 21
注意看,此时nums2,保存了原始数组的信息。
切换为:选择2;使用nums2 = nums1,问题来了,注意看nums2的数组变成了排序后的nums1.
Nums1 = 0 2 3 10 8 11 21
Nums2 = 0 2 3 8 10 11 21
总结,直接把对象object1 = object2,顺序再对原始赋值object2对象操作,那么object1也会改变?至少数组是这样子。下面我们来看String如何。
String originalString = "abcdefg"; String targetString = originalString; originalString = originalString.substring(2); System.out.println("originalString = "+originalString); System.out.println("targetString = "+targetString);
输出结果:
originalString = cdefg
targetString = abcdefg
说明String真正的被赋值到新的对象空间。
那么ArrayList如何呢?
ArrayList<Integer> originaList = new ArrayList<Integer>(); originaList.add(0); originaList.add(1); originaList.add(2); originaList.add(3); ArrayList<Integer> targetList = originaList; // ArrayList<Integer> targetList = (ArrayList<Integer>) originaList.clone(); originaList.set(0, 10); targetList.set(1, 20); System.out.println(targetList); System.out.println(originaList);
输出结果:
[10, 20, 2, 3]
[10, 20, 2, 3]
可以看到只用用相等,ArrayList 会把这两个对象指向同一个地址空间,
假如需要保存其中一个,最佳的办法就是object的clone方法:
研究半天,我在想有没有一个克隆方法,类似于Arrays.copyOf呢?原来java直接给object类构造了clone方法,这个方法,轻松解决我的疑虑。
不管是String,还是int[],又或者是ArrayList(),统统使用object.clone();再来一个强制类型转换,非常安全;