System.out.println(Arrays.toString(obj4));
}
//获取Object数组中的字符串类型数据
private static void getStringArrayFromObjectArray2() {
Object[] obj3 = { 1, 2, 3, "4", "5" };
String[] obj4 = new String[5];
try {
System.arraycopy(obj3, 3, obj4, 3, 2);
} catch (Exception e) {
System.out.println("transfer exception:"+e);
}
System.out.println(Arrays.toString(obj3));
//[null, null, null, 4, 5]
System.out.println(Arrays.toString(obj4));
obj3[3] = "zhangssan";
System.out.println("查看是浅复制还是深复制~~~~~");
System.out.println(Arrays.toString(obj3));
System.out.println(Arrays.toString(obj4));
}
}
只有普通数据类型和String类型是深拷贝!
![](https://img-blog.csdnimg.cn/20210126191921733.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70)
### 2、二维数组(浅拷贝)
//二维数组
public static void twoArray() {
int[] arr1 = {1, 2};
int[] arr2 = {3, 4};
int[] arr3 = {5, 6};
int[][] src = new int[][]{arr1, arr2, arr3};
print("原始模样:", src);
int[][] dest = new int[3][];
System.arraycopy(src, 0, dest, 0, 3);
System.out.println("改变前");
print("src = ", src);
print("dest = ", dest);
//原数组改变后观察新数组是否改变,改变->浅复制,不改变->深复制
src[0][0] = -1;
System.out.println("改变后");
print("src = ", src);
print("dest = ", dest);
}
//二维数组toString()
private static void print(String string, int[][] arr) {
System.out.print(string);
for (int[] a : arr) {
for (int i : a) {
System.out.print(i + " ");
}
System.out.print(",");
}
System.out.println();
}
二维数组属于浅拷贝,原始数组改变后,复制的数据也发生了改变!
![](https://img-blog.csdnimg.cn/20210126192158962.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70)
### 3、对象复制(深拷贝?)
![](https://img-blog.csdnimg.cn/20210126193123955.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2d1b3J1aV9qYXZh,size_16,color_FFFFFF,t_70)
四、System.arraycopy是不安全的
-----------------------
### 1、代码实例
多线程对数组进行复制,看System.arraycopy线程是否安全?
package com.guor.test.javaSE.collection;
import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ArrayTest2 {
private static int[] arrayOriginal = new int[1024 * 1024 * 10];
private static int[] arraySrc = new int[1024 * 1024 * 10];
private static int[] arrayDest = new int[1024 * 1024 * 10];
private static ReentrantLock lock = new ReentrantLock();
private static void modify() {
for (int i = 0; i < arraySrc.length; i++) {
arraySrc[i] = i + 1;
}
}
private static void copy() {
System.arraycopy(arraySrc, 0, arrayDest, 0, arraySrc.length);
}
private static void init() {
for (int i = 0; i < arraySrc.length; i++) {
arrayOriginal[i] = i;
arraySrc[i] = i;
arrayDest[i] = 0;
}
}
private static void doThreadSafeCheck() throws Exception {
for (int i = 0; i < 100; i++) {
System.out.println("run count: " + (i + 1));
init();
Condition condition = lock.newCondition();
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
condition.signalAll();
lock.unlock();
copy();
}
}).start();
lock.lock();
// 这里使用 Condition 来保证拷贝线程先已经运行了.
condition.await();
lock.unlock();
Thread.sleep(2); // 休眠2毫秒, 确保拷贝操作已经执行了, 才执行修改操作.
modify();
// 如果 System.arraycopy 是线程安全的, 那么先执行拷贝操作, 再执行修改操作时, 不会影响复制结果, 因此 arrayOriginal 必然等于 arrayDist;
if (!Arrays.equals(arrayOriginal, arrayDest)) {
throw new RuntimeException("System.arraycopy is not thread safe");
}
}
}
public static void main(String[] args) throws Exception {
//doThreadSafeCheck();
executeTime();
}
private static void executeTime() {
String[] srcArray = new String[1000000];
String[] forArray = new String[srcArray.length];
String[] arrayCopyArray = new String[srcArray.length];
//初始化数组
for(int i = 0 ; i < srcArray.length ; i ++){
srcArray[i] = String.valueOf(i);
}
long forStartTime = System.currentTimeMillis();
for(int index = 0 ; index < srcArray.length ; index ++){
forArray[index] = srcArray[index];
}
long forEndTime = System.currentTimeMillis();
System.out.println("for方式复制数组:" + (forEndTime - forStartTime));
long arrayCopyStartTime = System.currentTimeMillis();
System.arraycopy(srcArray,0,arrayCopyArray,0,srcArray.length);
long arrayCopyEndTime = System.currentTimeMillis();
System.out.println("System.arraycopy复制数组:" + (arrayCopyEndTime - arrayCopyStartTime));
}
}