System.arraycopy

//java.lang.System#arraycopy
/**
 * @param src     被拷贝的数组
 * @param srcPos  从数组那里开始
 * @param dest    目标数组
 * @param destPos 从目标数组那个索引位置开始拷贝
 * @param length  拷贝的长度 
 * 此方法是没有返回值的,通过 dest 的引用进行传值
 */
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);
  1. src:源数组
  2. srcPos:源数组要复制的起始位置
  3. dest:目标数组
  4. destPos:目的数组放置的起始位置
  5. length:要复制的长度

注意:src and dest都必须是同类型或者可以进行转换类型的数组


int[] srcArr = {1, 4, 6, 8, 6};
int[] destArr = new int[srcArr.length];
//全部复制
System.arraycopy(srcArr,0, destArr, 0, srcArr.length);
//[1, 4, 6, 8, 6]
System.out.println(Arrays.toString(destArr));
int[] srcArr = {1, 4, 6, 8, 6};
int[] destArr = new int[srcArr.length];
//srcArr中下标3开始,复制两个元素,重destArr开头开始填充
System.arraycopy(srcArr,3, destArr, 0, 2);
//[8, 6, 0, 0, 0]
System.out.println(Arrays.toString(destArr));
int[] srcArr = {1, 4, 6, 8, 6};
int[] destArr = new int[srcArr.length];
//srcArr中下标3开始,复制两个元素,重destArr小标2开头开始填充
System.arraycopy(srcArr,3, destArr, 2, 2);
//[0, 0, 8, 6, 0]
System.out.println(Arrays.toString(destArr));
int[] srcArr = {1, 4, 6, 8, 6};
int[] destArr = new int[srcArr.length];
//全部复制
System.arraycopy(srcArr, 0, destArr, 0, srcArr.length);
//[1, 4, 6, 8, 6]
System.out.println(Arrays.toString(destArr));
srcArr[2] = 666;
//基本值类型的数组,复制的是值,复制出来的数组跟原数组没有任何关系
//[1, 4, 6, 8, 6]
System.out.println(Arrays.toString(destArr));
//只有原数组才被修改了的
//[1, 4, 666, 8, 6]
System.out.println(Arrays.toString(srcArr));

 

class User {
    private String userName;
    private Integer userAge;
    public User(String userName, Integer userAge) {
        this.userName = userName;
        this.userAge = userAge;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public Integer getUserAge() {
        return userAge;
    }
    public void setUserAge(Integer userAge) {
        this.userAge = userAge;
    }
    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", userAge=" + userAge +
                '}';
    }
}
User[] srcUser = {new User("蔡徐坤", 18), new User("乔陛萝", 58)};
User[] destUser = new User[srcUser.length];
System.arraycopy(srcUser, 0, destUser, 0, srcUser.length);
System.out.println(Arrays.toString(destUser));

浅拷贝拷贝的是对象的引用,如果对象里面是基本类型也没有影响,应为我们拷贝的是对象的引用

User[] srcUser = {new User("蔡徐坤", 18), new User("乔陛萝", 58)};
User[] destUser = new User[srcUser.length];
System.arraycopy(srcUser, 0, destUser, 0, srcUser.length);

//[User{userName='蔡徐坤', userAge=18}, User{userName='乔陛萝', userAge=58}]
System.out.println(Arrays.toString(destUser));
//修改原数组的数据
srcUser[1].setUserName("我不能露脸");
//打印目的数组,可以发现拷贝的只是引用(浅拷贝)
//[User{userName='蔡徐坤', userAge=18}, User{userName='我不能露脸', userAge=58}]
System.out.println(Arrays.toString(destUser));
User[] srcUser = {new User("蔡徐坤", 18), new User("乔陛萝", 58)};
User[] destUser = new User[srcUser.length];
System.arraycopy(srcUser, 0, destUser, 0, srcUser.length);
//同一个对象
//true
//true
for(int i = 0; i < srcUser.length; i++){
    System.out.println(srcUser[i] == destUser[i]);
}
class User {
    String userName;
    int userAge;
    public User(String userName, Integer userAge) {
        this.userName = userName;
        this.userAge = userAge;
    }
    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                ", userAge=" + userAge +
                '}';
    }
}

User[] srcUser = {new User("蔡徐坤", 18), new User("乔陛萝", 58)};
User[] destUser = new User[srcUser.length];
System.arraycopy(srcUser, 0, destUser, 0, srcUser.length);

//[User{userName='蔡徐坤', userAge=18}, User{userName='乔陛萝', userAge=58}]
System.out.println(Arrays.toString(destUser));
//修改原数组的数据
srcUser[1].userName = "我不能露脸";
srcUser[1].userAge = 66;
//打印目的数组,可以发现拷贝的只是引用(浅拷贝)
//[User{userName='蔡徐坤', userAge=18}, User{userName='我不能露脸', userAge=66}]
System.out.println(Arrays.toString(destUser));

BufferedReader源码中的fill()函数用到了System.arraycopy(cb, markedChar, cb, 0, delta)方法,用来进行标记内容拷贝 

//java.io.BufferedReader#fill
if (readAheadLimit <= cb.length) {  
	 // 若“当前标记的长度”没有超过了“标记上限(readAheadLimit)”,  
	 // 并且“标记上限(readAheadLimit)”小于/等于“缓冲的长度”;  
	 // 则先将“下一个要被读取的位置,距离我们标记的置符的距离”间的字符保存到cb中。  
	 System.arraycopy(cb, markedChar, cb, 0, delta);  
	 markedChar = 0;  
	 dst = delta;  
 } else {  
	 // 若“当前标记的长度”没有超过了“标记上限(readAheadLimit)”,  
	 // 并且“标记上限(readAheadLimit)”大于“缓冲的长度”;  
	 // 则重新设置缓冲区大小,并将“下一个要被读取的位置,距离我们标记的置符的距离”间的字符保存到cb中。  
	 char ncb[] = new char[readAheadLimit];  
	 System.arraycopy(cb, markedChar, ncb, 0, delta);  
	 cb = ncb;  
	 markedChar = 0;  
	 dst = delta;  
 }  

class Student implements Cloneable {
    private String name;
    private int age;
    public Student() {}
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
}
Student s1 = new Student("蔡徐坤", 18);
//s1:	Student{name='蔡徐坤', age=18}
System.out.println("s1:\t" + s1);

//使用clone方法实现克隆
Object obj = s1.clone();
Student s2 = (Student) obj;
//s2:	Student{name='蔡徐坤', age=18}
System.out.println("s2:\t" + s2);
//s1 == s2:	false
System.out.println("s1 == s2:\t" + (s1 == s2));

//此处也可以实现复制,但是此种方法是将s1的地址给了s3,这是如果改变s3里面的东西s1也会跟着变化,但是由于s2是克隆的s1,所以s2并不会被改变
Student s3 = s1;
//s3:	Student{name='蔡徐坤', age=18}
System.out.println("s3:\t" + s3);

s3.setAge(68);
s3.setName("乔陛萝");

//s1:	Student{name='乔陛萝', age=68}
System.out.println("s1:\t" + s1);
//s2:	Student{name='蔡徐坤', age=18}
System.out.println("s2:\t" + s2);
//s3:	Student{name='乔陛萝', age=68}
System.out.println("s3:\t" + s3);

https://blog.csdn.net/qq_40794973/article/details/102414911

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值