java.lang.Cloneable的理解

以前也用过这个接口,那时是直接所有的东西都自己写了,也没发现问题。最近无意间发现这个接口的实现并不是想象中的那样,所以稍微研究了下,给大家分享一下。

步骤:1、建立两个简单的POJO:Teacher和Student

2、Teacher类实现了Cloneable接口,重写clone方法

3、在main方法中建立teacher,然后clone,比较teacher和clone出来的teacher

Teacher类:

public class Teacher implements Cloneable,Serializable{

private String name;
    
    private String sex;
    
    private int age;
    
    private List<Student> list;

public String getName() {
        return name;
    }

public void setName(String name) {
        this.name = name;
    }

public String getSex() {
        return sex;
    }

public void setSex(String sex) {
        this.sex = sex;
    }

public List<Student> getList() {
        return list;
    }

public void setList(List<Student> list) {
        this.list = list;
    }
    
    public int getAge() {
        return age;
    }

public void setAge(int age) {
        this.age = age;
    }

@Override
    protected Teacher clone() throws CloneNotSupportedException {
        
        Teacher t = (Teacher)super.clone();
        
        return t;
    }
    
    public Teacher deepClone() throws IOException, ClassNotFoundException
    {
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        ObjectOutputStream temp_out = new ObjectOutputStream(out);  
        temp_out.writeObject(this);  
 
        ByteArrayInputStream input = new ByteArrayInputStream(out.toByteArray());  
        ObjectInputStream temp_input = new ObjectInputStream(input);  
        return (Teacher) temp_input.readObject();
    }
}

Student类:

public class Student implements Serializable{

private String stName;
    
    private String stSex;

public String getStName() {
        return stName;
    }

public void setStName(String stName) {
        this.stName = stName;
    }

public String getStSex() {
        return stSex;
    }

public void setStSex(String stSex) {
        this.stSex = stSex;
    }
}

main:

public class MainTest {

public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
       List<Student> list = new ArrayList<Student>();
        
        Student st = new Student();
        
        st.setStName("stname");
        
        st.setStSex("f");
        
        list.add(st);
        
        Teacher te = new Teacher();
        
        te.setAge(19);
        
        te.setList(list);
        
        te.setName("tename");
        
        te.setSex("tesex");
        
        Teacher cl = te.clone();
        
        cl.setAge(12);
        
        System.out.println("淺複製"+ (cl == te));
        
        //内存中的地址
        System.out.println(cl.getName() == te.getName());
        
        System.out.println(cl.getList() == te.getList());
        
        System.out.println("source:"+te.getAge()+"<==>clone:"+cl.getAge());

     
        
        Teacher  deep = te.deepClone();

System.out.println("深複製"+(cl == te));

        
        System.out.println(deep.getName() == te.getName());
        
        System.out.println(deep.getList() == te.getList());

    }
}

输出结果:

淺複製false
true
true
source:19<==>clone:12
深複製false
false
false

从输出结果可以得出的结论

1、对于浅复制来说,当调用clone方法返回的cl对象跟te对象不是同一个对象(地址不一样),但是内部的对象引用却是引用的相同对象(地址一样);而对于基本类型age(int)来说,克隆的对象cl跟原始对象te不是同一个(如果是同一个的话,修改任何一个,另外对象的内容也会变化)

2、对于深复制来说,克隆出来的对象不但跟原始对象不一样(地址不一样),而且内部应用对象也不一样了(地址不一样)

时间: 2024-11-07 21:04:58

java.lang.Cloneable的理解的相关文章

Java核心技术之深入理解对象的生命周期

1 总体说明 Java类的初始化 对象的创建与初始化 对象的销毁 对象的复制 2 Java类的初始化 自然界的任何生物都有个由生到死的过程. 而当源代码编译成class文件被JVM的类加载器装载到内存中后,也会经历这么一个由生到死的过程,接下来就分析Java类的初始化到底做了哪些事情.这里暂时不谈JVM将class文件装载到内存的详细细节,只是从类的五种成员来观察类的初始化 之前提到过类的五种成员,包含属性,方法,构造器,代码块以及静态代码块五个部分.其中静态代码块和静态属性(也就是static

java.lang.Object

java.lang包在使用的时候无需显示导入,编译时由编译器自动导入. Object类是类层次结构的根,Java中所有的类从根本上都继承自这个类. Object类是Java中唯一没有父类的类. 其他所有的类,包括标准容器类,比如数组,都继承了Object类中的方法. Object类中的方法 构造方法:public Object() 文档中的类概览: Java中的每个类都具有定义在Object类中的这些方法. protected Object clone() Creates and returns

Java中hashcode的理解

原文链接http://blog.csdn.net/chinayuan/article/details/3345559 如何理解hashCode的作用: 以 java.lang.Object来理解,JVM每new一个Object,它都会将这个Object丢到一个Hash哈希表中去,这样的话,下次做 Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象.这样做的目的是提高取对象的效率.具体过程是这 样: 1.new Object(),JVM根据这个对象的H

深入理解java.lang.String

String类是Java编程中应用最广泛的类,所以每一位程序员都应该仔细研究一番String类的内部实现,这样对我们理解String对象的工作机制.避免错误和提升代码效率有很大好处.你若打开Java语言规范 (Java 9),可以看到4.3.3节中对String对象的简述[1]: String对象的实例,表示Unicode码的序列. 一个String对象,有一个恒定不变的值. 字符串字面量是对String实例的引用. 非常量表达式时,“+“操作符连接两个String对象,总是会隐式地产生一个新的

【转载】java项目中经常碰到的内存溢出问题: java.lang.OutOfMemoryError: PermGen space, 堆内存和非堆内存,写的很好,理解很方便

Tomcat Xms Xmx PermSize MaxPermSize 区别 及 java.lang.OutOfMemoryError: PermGen space 解决 解决方案 在 catalina.bat 里的 蓝色代码前加入: 红色代码 rem ----- Execute The Requested Command --------------------------------------- set JAVA_OPTS=%JAVA_OPTS%-server -Xms800m -Xmx1

Java总结篇系列:java.lang.Object

从本篇开始,将对Java中各知识点进行一次具体总结,以便对以往的Java知识进行一次回顾,同时在总结的过程中加深对Java的理解. Java作为一个庞大的知识体系,涉及到的知识点繁多,本文将从Java中最基本的类java.lang.Object开始谈起. Object类是Java中其他所有类的祖先,没有Object类Java面向对象无从谈起.作为其他所有类的基类,Object具有哪些属性和行为, 是Java语言设计背后的思维体现. Object类位于java.lang包中,java.lang包包

Java.lang.Object.clone()分析

首先,看一下源码: 1 public class Object { 2 protected native Object clone() throws CloneNotSupportedException; 3 } 由源代码我们会发现: 第一:Object类的clone()方法是一个native方法,native方法的效率一般来说都是远高于Java中的非native方法.这也解释了为什么要用Object中clone()方法而不是先new一个类,然后把原始对象中的信息复制到新对象中,虽然这也实现了c

Java中泛型的理解

Java中的泛型,本质上来说,就是是参数化类型,就是说所操作的数据类型被指定为一个参数,而不是确定的某种类型.这种数据类型可以用在类.接口和方法创建中.即泛型类.泛型接口.泛型方法.这样说可能不够生动,来举些例子说明一下. 例子一 我们通过 例子一 来简单看看泛型的应用场景.下面的情况中,没有使用泛型: public class FanXingTest { public static void main(String[] args) { ArrayList arrayList = new Arr

java.lang.Object底层代码分析-jdk1.8

首先先来说明两件事情 1.后面的一些博客都会对jdk底层的方法进行一些分析,因为我个人开发了2年多,发现有很多事情还不是清楚,当我今天再好好底层源码的时候还是有不少的收获,所以和大家分    享一下,我只要参考一下相关文档 jdk1.8api:https://docs.oracle.com/javase/8/docs/api/index.html 代码下载地址:https://gitee.com/luanmihun/java-jdk-study 2.为什么要分析jdk1.8的版本,只是一些个人的