http://www.cnblogs.com/zhengbin/p/5671403.html

http://www.cnblogs.com/jjdcxy/p/5870524.html

 

Java数组拷贝主要有四种方法,分别是循环赋值,System.arraycopy(),Arrays.copyOf()(或者Arrays.copyOfRange)和clone()方法。下面分别介绍一下这几种拷贝。

循环拷贝(速度相对比较慢)

循环拷贝其实没什么好说的啦,就是用一个for循环进行元素的逐个拷贝,进行深拷贝或者浅复制这个大家可以自己把握。

System.arraycopy(浅拷贝)

这个是系统提供的拷贝方式,也是我们推荐使用的拷贝方式,它是浅拷贝,也就是说对于非基本类型而言,它拷贝的是对象的引用,而不是去新建一个新的对象。通过它的代码我们可以看到,这个方法不是用java语言写的,而是底层用c或者c++实现的,因而速度会比较快。

public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);                  

通过源代码我们可以看到,关键字native说明它不是用java语言写的,而是调用其他语言的代码。

Arrays.copyOf(浅拷贝)

这个方法也是浅拷贝,为什么呢?我们看一下它的源代码就知道了。

public static byte[] copyOfRange(byte[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
byte[] copy = new byte[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}

实际上它调用的就是System.arraycopy,所以肯定也是浅拷贝。

Object.clone

clone()比较特殊,对于对象而言,它是深拷贝,但是对于数组而言,它是浅拷贝。

对象拷贝

首先讲一下对象的拷贝,它是深拷贝,大家可以用对象去测试一下。下面我们看一下它的源代码:

protected native Object clone() throws CloneNotSupportedException;

这里也有native关键字,所以也是底层的C语言实现的。 
还要注意的是,这里修饰符是protected,也就是说,我们创建了一个Object类以后,是不能直接调用这个clone()方法的,因为protected关键字只允许同一个包内的类和它的子类调用,所以我们声明一个object类时,肯定不是同一个包内,所以就不能去调用它。

要调用这个方法,就需要我们写一个类,然后声明实现cloneable接口就好了,不需要去显示地声明继承于object,因为java中的类如果不显示说明父类的话,默认父类就是object。然后我们继承这个方法:

@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}

这里需要是,为了能够在不同包内去调用这个方法,我们需要把这个权限升级为public。现在我们就可以调用这个类的clone()方法去拷贝我们的类了。

数组拷贝

对于数组而言,它不是简单的将引用赋值为另外一个数组引用,而是创建一个新的数组。但是我们知道,对于数组本身而言,它它的元素是对象的时候,本来数组每个元素中保存的就是对象的引用,所以,拷贝过来的数组自然而言也是对象的引用,所以对于数组对象元素而言,它又是浅拷贝。我们用以下代码验证一下:


class Aby implements Cloneable{
public int i;
public Aby(int i) {
this.i = i;
}
@Override
public Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
} public class Solution { public static void main(String[] args) throws CloneNotSupportedException {
Aby aby1 = new Aby(1);
Aby aby2 = (Aby) aby1.clone();
aby1.i = 2;
System.out.println(aby1.i); //2
System.out.println(aby2.i); //1 Aby[] arr = {aby1,aby2}; Aby[] arr2 = arr.clone();
arr2[0].i = 3;
System.out.println(arr[0].i); //3
System.out.println(arr2[0].i); //3
}
}

java 数组复制的更多相关文章

  1. java数组复制的几种常见用法

    1.1数组复制的几种常见用法 1.1.1System.arraycopy的用法 int[] src = {1,3,5,7,9,11,13,15,17}; int[] dest = {2,4,6,8,1 ...

  2. java数组复制的方式和效率比较

    java中,数组的复制有以下三种方式: 1. 调用System.arraycopy(Arrays.copyOfRange可以当作第四种,但是底层调用的是System.arraycopy,所以,认为是同 ...

  3. Java数组复制、遍历、反转

    /* 1.数组长度,直接length 即可! 2.min()/max(),需要调用库! 3.数组的复制 ,遍历复制,或者直接命名相等 即可! 4.数组反转时,直接折中即可!对调两重循环麻烦! */ i ...

  4. Java 数组复制之clone方法

    一.源码 public class Test1 { public static void main(String[] args) { // Student[] arrs = new Student[] ...

  5. Java数组复制

    System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制.其函数原型是: public static void arraycopy(Object src, int sr ...

  6. java数组复制的简单方法(一)

    总结:主要是用a数组的长度等于b数组,然后a数组赋值给b数组,我不能想到这个办法,我还是不理解数组中length属性的含义 这里数组并没有正真复制过来,而是一个引用 package com.a; // ...

  7. java数组复制===clone()

    总结:使用方法原理弄清楚 package com.a; public class gjsopb { public static void main(String[] args) { int a[] = ...

  8. Java 数组的三种创建方法,数组拷贝方法

    public static void main(String[] args) {//创建数组的第一种方法int[] arr=new int[6];int intValue=arr[5];//Syste ...

  9. JAVA 数组算法(复制、查找、插入)

    一.复制数组算法 //数组复制算法 public class Test{ public static void main(String[] args){ int[] arrA = {100,800,5 ...

随机推荐

  1. Python 输出文件内容到网络端口

    Python 输出文件内容到网络端口 $ cat mySocketTest.py import sys import time import socket if __name__ == "_ ...

  2. 使用 xUnit 编写 ASP.NET Core 单元测试

    还记得 .NET Framework 的 ASP.NET WebForm 吗?那个年代如果要在 Web 层做单元测试简直就是灾难啊..NET Core 吸取教训,在设计上考虑到了可测试性,就连 ASP ...

  3. final和static关键字

    1.如果类只有静态方法,可以将构造函数标记为private以避免被初始化: 2.常量同时标记为static和final,常量名全部大写,下划线连接: 3.final修饰一个成员变量(属性),必须要显示 ...

  4. 使用FaceNet 图像相识度对比

    1. 模型结构:

  5. Unit 4.css的导入方式和选择器

    一.什么是css CSS是指层叠样式表(Cascading Style Sheets),样式定义如何显示HTML元素,样式通常又会存在于样式表中.也就是说把HTML元素的样式都统一收集起来写在一个地方 ...

  6. SpringCloud入门(一)

    一.微服务概述 1.什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事. 与微服务相对的叫巨石 ...

  7. MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client

    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';

  8. mongoDB 其他数据类型

    时间 类型 获取当前时间 new Date() 自动生成当前时间(国际标准时间) db.class.insertOne({book:"数学",date:new Date()}) D ...

  9. centos 下安装显卡驱动步骤

    一. 先下载自己显卡对应的linux版本的驱动文件, 一般都是.run的一个文件. 二.如果是新安装的系统,先安装编译环境,gcc,kernel-devel,kernel-headers  (联网) ...

  10. 深入理解JVM(4)——对象的创建和访问

    1.对象的创建 在语言层面上,创建对象(例如克隆,反序列化)通常仅仅是一个new关键字而已. 在虚拟机中,对象(文中讨论的对象限于普通 Java 对象,不包括数组和 Class 对象等)的创建过程如下 ...