Java集合面试题_java是什么

Java集合面试题_java是什么Java中的浅拷贝与深拷贝很多时候,我们期望去拷贝某个对象的副本。在Java中如果使用=赋值操作,其实际上会让两个引用变量指向同一个对象;而如果重新new一个新对象,再对各字段进行赋值操作时,将十分繁琐。为此在Java的Object类中,提供了一个clone方法,其可拷贝对象副本clone方法与Cloneable接口Cloneable接口的源码如下publicinterfaceCloneable{}注释第一段一个类实现了Cloneable接口,以向Object.c

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

Java 中的拷贝

由于java中只有值传递,u2 = u1,拿到的是u1的地址,u2和u1指向的是同一个内存区域,u1改变值,u2也会改变。

        UseCloneable u1 = new UseCloneable();
        UseCloneable u2 = u1;
        u1.a = 10;

在这里插入图片描述

那么我们怎么构造一个新的对象呢

        u2 = new UseCloneable();
        u2.a = u1.a;

但是如果有20个30个字段,这么写就比较臃肿。

clone 方法 与 Cloneable 接口

在这里插入图片描述


通俗理解

实现该接口并重写方法来实现拷贝。没实现该接口调用clone方法会报错。

Ojbect类中的clone方法

访问修饰符为protected ,只能由子类或者同包的类调用。

protected native Object clone() throws CloneNotSupportedException;

我们尝试调用clone方法,会提示CloneNotSupportedException

public static void main(String[] args) throws CloneNotSupportedException{ 
   
        UseCloneable u1 = new UseCloneable();
        u1.clone();
-------
Exception in thread "main" java.lang.CloneNotSupportedException: com.example.miccommon.collection.UseCloneable
	at java.lang.Object.clone(Native Method)
	at com.example.miccommon.collection.UseCloneable.main(UseCloneable.java:16)

实现接口实现拷贝过程

@Data
public class UseCloneable implements Cloneable { 
   

    private int a;
    private int b;
    private int c;
    private int d;
    private int e;
    private int f;
    private int g;

    public static void main(String[] args) throws CloneNotSupportedException { 
   

        UseCloneable vvvv = new UseCloneable();
        vvvv.setA(10);
        vvvv.setB(12);
        vvvv.setC(14);
        vvvv.setD(16);
        vvvv.setE(18);
        vvvv.setF(20);
        vvvv.setG(22);
        UseCloneable clone = (UseCloneable) vvvv.clone();
        System.out.println(clone);
    }

    @Override
    public String toString() { 
   
        return "UseCloneable{" +
                "a=" + a +
                ", b=" + b +
                ", c=" + c +
                ", d=" + d +
                ", e=" + e +
                ", f=" + f +
                ", g=" + g +
                '}';
    }
}
-------
UseCloneable{ 
   a=10, b=12, c=14, d=16, e=18, f=20, g=22}

可以看到是两个不同的对象

在这里插入图片描述

重写clone方法,来自定义克隆内容。

  @Override
    protected Object clone() throws CloneNotSupportedException { 
   
        UseCloneable clone = (UseCloneable) super.clone();
        clone.setA(999);
        return clone;
    }
-------
UseCloneable{ 
   a=999, b=12, c=14, d=16, e=18, f=20, g=22}

ArrayList 中相关的实现

public Object clone() { 
   
        try { 
   
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) { 
   
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
        ArrayList<Object> objects = new ArrayList<>();
        objects.add("123");
        Object o = objects.clone();
        System.out.println(o);

在这里插入图片描述

深拷贝

构造一个类Deep,通过clone拷贝。

@Data
public class UseCloneable implements Cloneable { 
   

    Deep deep;


    public static void main(String[] args) throws CloneNotSupportedException { 
   
        UseCloneable source = new UseCloneable();
        source.deep = new Deep();
        UseCloneable target = (UseCloneable) source.clone();
        System.out.println(target);
    }

}

class Deep { 
   

}

虽然source和target已经不是同一个对象,但是两个对象中的deep都是同一个指向。

在这里插入图片描述

我们稍作改造来看看有什么影响,在Deep类中加入属性A。

@Data
public class UseCloneable implements Cloneable { 
   

    Deep deep;

    public static void main(String[] args) throws CloneNotSupportedException { 
   
        UseCloneable source = new UseCloneable();
        source.deep = new Deep();
        source.deep.setA(10);
        UseCloneable target = (UseCloneable) source.clone();
        System.out.println(target);
        source.deep.setA(5);
        System.out.println(target);
    }

}

@Data
class Deep { 
   

    private int a ;

}
--------
UseCloneable(deep=Deep(a=10))
UseCloneable(deep=Deep(a=5))

对source的改动会影响到target中deep的字段,这样肯定是不合理的于是我们。

我们对代码进行改动

@Data
public class UseCloneable implements Cloneable { 
   

    Deep deep;

    public static void main(String[] args) throws CloneNotSupportedException { 
   
        UseCloneable source = new UseCloneable();
        source.deep = new Deep();
        source.deep.setA(10);
        UseCloneable target = (UseCloneable) source.clone();
        System.out.println(target);
        source.deep.setA(5);
        System.out.println(target);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException { 
   
        UseCloneable target = (UseCloneable) super.clone();
        Deep deep = target.getDeep();
        if (deep != null){ 
   
            Deep targetDeep = (Deep) target.getDeep().clone();
            target.setDeep(targetDeep);
        }
        return target;
    }
}

@Data
class Deep implements Cloneable { 
   

    private int a;

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

可以看到两个对象的deep的指向已经改变。

在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/182246.html原文链接:https://javaforall.net

(0)
上一篇 2022年10月13日 下午11:46
下一篇 2022年10月13日 下午11:46


相关推荐

  • python 遍历文件夹下所有图片

    python 遍历文件夹下所有图片水电费

    2022年5月20日
    47
  • hostapd中beacon流程

    hostapd中beacon流程hostapd中beacon流程ieee802_11_build_ap_params()-ieee802_11_set_beacon()–ieee802_11_set_beacons()—handle_assoc()—hostapd_2040_coex_action()—hostapd_intolerant_add()—update_ht_state()—ap_…

    2022年5月11日
    46
  • NTP 时间服务器「建议收藏」

    NTP时间服务器,为客户机提供标准时间原理:NTP(NetworkTimeProtocol,网络时间协议)是用来使计算机时间同步的一种协议。它可以使计算机对其服务器或时钟源做同步化,它可以提供高精准度的时间校正1、客户端安装chrony软件与NTP服务器沟通]#yum-yinstallchrony2、修改配置文件/etc/chrony.conf指定服务端…

    2022年4月6日
    48
  • System.setProperty() 学习「建议收藏」

    System.setProperty() 学习「建议收藏」/**设置指定键对值的系统属性*setProperty(Stringprop,Stringvalue);**参数:*prop-系统属性的名称。*value-系统属性的值。**返回:*系统属性以前的值,如果没有以前的值,则返回null。**抛出:*SecurityExceptio

    2022年7月13日
    60
  • 网页刷流量软件开发中的困惑

    网页刷流量软件开发中的困惑客户要求:1.利用代理IP访问指定网页.并且点击指定位置2.代理IP获取方式最好为吸附.吸附我提供的地址.或许你有更好的方案最佳.3.如果能够控制代理访问量最好.比如我在指定的时间内10点-11点的时候需要1W的量.那么程序刷到1W的量就自动停止.4.可以用协议开发.但是协议一定要支持统计代码.也就是一定要让后台统计到具体数据.我的解决方案有二:。一是模…

    2026年4月18日
    4
  • SPSS实现卡方检验

    SPSS实现卡方检验总目录 SPSS 学习整理 SPSS 卡方检验目的适用情景数据处理 SPSS 操作 SPSS 输出结果分析知识点目的统计样本的实际观测值与理论推断值之间的偏离程度 如完全相等 卡方为 0 适用情景数据处理 SPSS 操作 SPSS 输出结果分析基本信息残差也就是期望值和实际值的差值最主要的分析结果 卡方为 0 571 显著性为 0 989 大于 0 05 接受原假设 认为样本分布于期望没有差异 即筛子是均匀分布的 知识点

    2026年3月26日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号