java类型 -- 拷贝

拷贝的基本含义


拷贝,也就是复制的意思。
体现在电脑里,也就是说在存储中产生一个与原对象相同的复制对象。

Java中与复制相关的一些规则


在java中拷贝是无处不在的。比如说,传参,返回值,赋值等等。
java出于效率的考虑,会 区分对待基本数据类型(int,double…),以及对象的拷贝。
注意:

- 对于基本数据类型的拷贝代价是比较小的,所以可以直接复制值。
- 对于对象的复制,代价可能是很大的,所以基于简单的原则,java一般情况下只是复制其引用。【基本的一个原则】

java拷贝的代码实例

(1)使用clone.

1- java 还是考虑到了用户在复制方面的需求,所以通过clone方法,来供用户实现自己的需求。
2- java默认实现的clone方法,是不完全的拷贝(浅拷贝),它拷贝的效果,是为新生成的对象重新分配内存空间,并且对于基本的数据类型进行复制。 然而,对于被复制对象内部的对象,则是仅仅复制了其内部包含的对象的引用。 【这是符合前面说的“简单原则”的】

下面是与之相关的实例代码:

public class CopyTestClass {

    public static void main(String[] args) throws CloneNotSupportedException {
        //1.创建一个对象first,并且给其成员变量赋值。
        Position first = new Position(1, 1, 1);
        first.layerAndBranch.put(55, 66);
        System.out.println(first.toString());

        //2.使用复制方法,并且将复制结果 给了引用 second.
        Position second = (Position) first.clone();

        //3.在second对象中,对成员变量进行修改。
        // 3.1.更改second中的基本类型。
        second.layer = 2;
        // 3.2.更改second中的map。
        second.layerAndBranch.put(55, 0);

        //4.输出结果。
        System.out.println(first.toString());
        System.out.println(second.toString());
    }

    //position 定义为了静态内部类。(实现clone方法)
    public static class Position implements Cloneable{
        public int layer;
        public int currentBranch;
        public int positionInBranch;
        public Map<Integer, Integer> layerAndBranch = new HashMap<Integer, Integer>();

        Position(int layer, int branch, int positionInBranch) {
            this.layer = layer;
            this.currentBranch = branch;
            this.positionInBranch = positionInBranch;
        }

        //重写了方法,便于观察。
        @Override
        public String toString() {
            return "[" + super.toString() + "]\n" + layer + "-" + currentBranch + "-" + positionInBranch +"\n"
        + "map: " + 55 + " ---> " +layerAndBranch.get(55);
        }

        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
}

输出结果:

  • 复制之后,对象的id是不一样的了,说明新生成了一个对象。
  • 修改复制对象(second)的基本类型(int)后,并不影响原对象的与之相关的成员。
  • 修改复制对象(second)的对象成员(map)后,对原对象造成了影响。
[javaTest.refTest.CopyTestClass$Position@a62812d]
1-1-1
map: 55 ---> 66
[javaTest.refTest.CopyTestClass$Position@a62812d]
1-1-1
map: 55 ---> 0
[javaTest.refTest.CopyTestClass$Position@490eb6ae]
2-1-1
map: 55 ---> 0

(2)使用序列化(Serializable)

该对象序列化成流,流中的对象是 虚拟机中对象的一个完整的拷贝。(包括:基本类型,其他成员对象)
代码实例:

public class CopyDeepTest {

    public static void main(String[] args) throws Exception {
        Position first = new Position(1, 1, 1);
        first.layerAndBranch.put(55, 66);
        System.out.println(first.toString());

        Position second = (Position) first.deepCopy();

        second.layer = 2;
        second.layerAndBranch.put(55, 0);
        System.out.println(first.toString());
        System.out.println(second.toString());
    }

    public static class Position implements Serializable {
        public int layer;
        public int currentBranch;
        public int positionInBranch;
        public Map<Integer, Integer> layerAndBranch = new HashMap<Integer, Integer>();

        Position(int layer, int branch, int positionInBranch) {
            this.layer = layer;
            this.currentBranch = branch;
            this.positionInBranch = positionInBranch;
        }

        @Override
        public String toString() {
            return "[" + super.toString() + "]\n" + layer + "-" + currentBranch + "-" + positionInBranch + "\n"
                    + "map: " + 55 + " ---> " + layerAndBranch.get(55);
        }

        public Object deepCopy() throws Exception {
            // 该对象序列化成流,流中的对象是 虚拟机中对象的一个完整的拷贝。(包括:基本类型,其他成员对象)
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            ObjectOutputStream oos = new ObjectOutputStream(bos);

            oos.writeObject(this);

            // 流转化为对象
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

            ObjectInputStream ois = new ObjectInputStream(bis);

            return ois.readObject();
        }
    }
}

输出结果:

  • 两个对象(源对象,复制对象)中都各有一个独立的map对象。
[javaTest.refTest.CopyDeepTest$Position@6208f57a]
1-1-1
map: 55 ---> 66
[javaTest.refTest.CopyDeepTest$Position@6208f57a]
1-1-1
map: 55 ---> 66
[javaTest.refTest.CopyDeepTest$Position@10d13e3e]
2-1-1
map: 55 ---> 0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值