精华内容
下载资源
问答
  • java序列化克隆 开发人员经常依靠3d方库来避免重新发明轮子,尤其是在Java世界中,Apache和Spring这样的项目如此盛行。 在处理这些框架时,我们通常很少或根本无法控制其类的行为。 这有时会导致问题。 例如,...

    java序列化深克隆

    开发人员经常依靠3d方库来避免重新发明轮子,尤其是在Java世界中,Apache和Spring这样的项目如此盛行。 在处理这些框架时,我们通常很少或根本无法控制其类的行为。

    这有时会导致问题。 例如,如果您想深克隆一个不提供合适克隆方法的对象,除了编写大量代码之外,您还有什么选择?

    通过序列化克隆

    最简单的方法是通过利用对象可序列化进行克隆。 Apache Commons提供了一种执行此操作的方法,但是为了完整起见,下面也是您自己执行此操作的代码。

    @SuppressWarnings("unchecked")
    public static  T cloneThroughSerialize(T t) throws Exception {
       ByteArrayOutputStream bos = new ByteArrayOutputStream();
       serializeToOutputStream(t, bos);
       byte[] bytes = bos.toByteArray();
       ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
       return (T)ois.readObject();
    }
    
    private static void serializeToOutputStream(Serializable ser, OutputStream os)
                                                              throws IOException {
       ObjectOutputStream oos = null;
       try {
          oos = new ObjectOutputStream(os);
          oos.writeObject(ser);
          oos.flush();
       } finally {
          oos.close();
       }
    }
    
    // using our custom method
    Object cloned = cloneThroughSerialize (someObject);
    
    // or with Apache Commons
    cloned = org.apache.commons.lang. SerializationUtils.clone(someObject);

    但是,如果我们要克隆的类不是可序列化的,并且我们无法控制源代码或者无法将其设置为可序列化该怎么办?

    选项1 – Java深度克隆库

    有一个不错的小程序库,它可以深度克隆几乎所有Java对象- 克隆 。 它利用Java的出色反射功能来提供优化的对象的深克隆版本。

    Cloner cloner=new Cloner();
    Object cloned = cloner.deepClone(someObject);

    如您所见,它非常简单有效,并且需要最少的代码。 除了这个简单的示例,它还具有一些更高级的功能,您可以在此处查看

    选项2 – JSON克隆

    如果我们无法将新库引入我们的代码库,该怎么办? 我们中有些人处理批准程序以引入新的库,对于一个简单的用例,可能不值得。

    好吧,只要我们有某种方式可以序列化和还原对象,就可以进行深层复制。 JSON通常被使用,因此它是一个很好的选择,因为我们大多数人都使用一个或另一个JSON库。

    Java中的大多数JSON库都可以有效地序列化任何POJO,而无需任何配置或映射。 这意味着,如果您具有JSON库并且不能或不会引入更多库来提供深度克隆,则可以利用现有的JSON库来获得相同的效果。 请注意,此方法将比其他方法慢,但是对于绝大多数应用程序,这不会引起任何性能问题。

    以下是使用GSON库的示例。

    @SuppressWarnings("unchecked")
    public static  T cloneThroughJson(T t) {
       Gson gson = new Gson();
       String json = gson.toJson(t);
       return (T) gson.fromJson(json, t.getClass());
    }
    // ...
    Object cloned = cloneThroughJson(someObject);

    请注意,仅当复制的对象具有默认的无参数构造函数时,这才可能起作用。 对于GSON,您可以使用实例创建者来解决此问题。 其他框架具有类似的概念,因此如果遇到无法修改的类且没有默认构造函数的问题,则可以使用该框架。


    结论

    我建议做的一件事是,对于需要克隆的任何类,都应该添加一些单元测试,以确保一切正常。 这可以防止对类的更改(例如,升级库版本)在您不知情的情况下破坏应用程序,尤其是在您设置了持续集成环境的情况下。

    我概述了几种在没有任何自定义代码的情况下克隆对象的方法。 如果您使用其他任何方法获得相同的结果,请分享。

    参考: Carfey Software Blog上的JCG合作伙伴 Craig Flichel从Java轻松深度克隆了Java中的可序列化和不可序列化的对象

    相关文章 :


    翻译自: https://www.javacodegeeks.com/2011/12/cloning-of-serializable-and-non.html

    java序列化深克隆

    展开全文
  • java序列化克隆 在我以前的文章中,我解释了深度克隆和浅层克隆之间的区别 , 以及复制构造函数和防御性复制方法比默认的Java克隆如何更好。 使用复制构造函数和防御性复制方法进行的Java对象克隆当然具有某些...

    java序列化深克隆

    在我以前的文章中,我解释了深度克隆浅层克隆之间区别以及复制构造函数防御性复制方法比默认的Java克隆如何更好。

    使用复制构造函数防御性复制方法进行的Java对象克隆当然具有某些优势,但是我们必须显式编写一些代码才能在所有这些方法中实现深度克隆。 而且,仍然有可能我们会错过某些东西并且不会得到深克隆的对象。

    正如在Java中创建对象的5种不同方式中所讨论的那样,反序列化序列化对象会创建一个状态与序列化对象相同的新对象。 因此,与上述克隆方法类似,我们也可以使用对象序列化和反序列化来实现深度克隆功能,并且通过这种方法,我们不必担心或编写用于深度克隆的代码,默认情况下会得到它。

    但是,使用序列化克隆对象会带来一些性能开销,如果我们只需要克隆对象并且不需要将其持久保存在文件中以备将来使用,则可以通过使用内存中序列化来改进它。

    我们将使用以下Employee类作为示例,其name
    作为状态的dojskills ,对于深度克隆,我们无需担心code> name字段,因为它是一个String对象,默认情况下所有
    弦在本质上是不变的

    您可以在《 如何在Java中创建不可变的类》以及《 为什么String是不可变的和Final》上阅读有关不可变性的更多信息。

     Employee class implements Serializable { 
         private static final long serialVersionUID = 2L; 
         private String name; 
         private LocalDate doj; 
         private List<String> skills; 
         public Employee(String name, LocalDate doj, List<String> skills) { 
             this .name = name; 
             this .doj = doj; 
             this .skills = skills; 
         } 
         public String getName() { return name; } name; } 
         public LocalDate getDoj() { return doj; } doj; } 
         public List<String> getSkills() { return skills; } skills; } 
         // Method to deep clone a object using in memory serialization 
         public Employee deepClone() throws IOException, ClassNotFoundException { 
             // First serializing the object and its state to memory using ByteArrayOutputStream instead of FileOutputStream. 
             ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
             ObjectOutputStream out = new ObjectOutputStream(bos); 
             out.writeObject( this ); 
             // And then deserializing it from memory using ByteArrayOutputStream instead of FileInputStream. 
             // Deserialization process will create a new object with the same state as in the serialized object, 
             ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); 
             ObjectInputStream in = new ObjectInputStream(bis); 
             return (Employee) in.readObject(); 
         } 
         @Override 
         public String toString() { 
             return String.format( "Employee{name='%s', doj=%s, skills=%s}" , name, doj, skills); 
         } 
         @Override 
         public boolean equals(Object o) { 
             if ( this == o) return true ; 
             if (o == null || getClass() != o.getClass()) return false ; 
             Employee employee = (Employee) o; 
             return Objects.equals(name, employee.name) && 
                 Objects.equals(doj, employee.doj) && 
                 Objects.equals(skills, employee.skills); 
         } 
         @Override 
         public int hashCode() { 
             return Objects.hash(name, doj, skills); 
         }  } 

    为了深度克隆Employee类的对象,我提供了一个
    deepClone()方法,通过使用将对象序列化到内存
    ByteArrayOutputStream而不是FileOutputStream并使用ByteArrayInputStream而不是FileInputStream将其反序列化。 在这里,我们将对象序列化为字节,然后再次将其从字节反序列化为对象。

    Employee类实现Serializable接口来实现序列化,这有其自身的劣势,我们可以通过使用Externalizable接口来自定义序列化过程来克服其中的某些劣势。

    我们可以在下面的测试中运行,以了解我们的克隆方法是深层克隆还是浅层克隆,此处所有==操作将返回false(因为两个对象是分开的),而所有equals将返回true(因为两者具有相同的内容)。

     public static void main(String[] args) throws IOException, ClassNotFoundException { 
      Employee emp = new Employee( "Naresh Joshi" , LocalDate.now(), Arrays.asList( "Java" , "Scala" , "Spring" )); 
      System.out.println( "Employee object: " + emp); 
      // Deep cloning `emp` object by using our `deepClone` method. 
      Employee clonedEmp = emp.deepClone(); 
      System.out.println( "Cloned employee object: " + clonedEmp); 
      System.out.println(); 
      // All of this will print false because both objects are separate. 
      System.out.println(emp == clonedEmp); 
      System.out.println(emp.getDoj() == clonedEmp.getDoj()); 
      System.out.println(emp.getSkills() == clonedEmp.getSkills()); 
      System.out.println(); 
      // All of this will print true because `clonedEmp` is a deep clone of `emp` and both have the same content. 
      System.out.println(Objects.equals(emp, clonedEmp)); 
      System.out.println(Objects.equals(emp.getDoj(), clonedEmp.getDoj())); 
      System.out.println(Objects.equals(emp.getSkills(), clonedEmp.getSkills()));  } 

    我们知道反序列化过程每次都会创建一个新对象,如果我们必须使我们的类单身,那将是不好的。 这就是为什么我们需要覆盖和禁用单例类的序列化,这可以通过提供writeReplace和readResolve方法来实现。

    与序列化类似,Java克隆也不能与单例模式一起使用,这就是为什么我们也需要覆盖和禁用它。 我们可以通过实现克隆的方式来做到这一点,以便它要么抛出
    CloneNotSupportedException或每次都返回相同的实例。

    您可以在Java CloningJava上阅读有关Java克隆和序列化的更多信息。
    Java序列化主题。

    您可以在此找到本文的完整源代码。
    Github存储库 ,请随时提供宝贵的反馈。

    翻译自: https://www.javacodegeeks.com/2019/08/deep-clone-using-java-memory-serialization.html

    java序列化深克隆

    展开全文
  • Java序列化克隆

    2013-04-18 13:52:33
    Java序列化克隆 2011-03-04 09:25 mojianpo JavaEye博客 我要评论(1) 字号:T | T 本篇文章主要对Java序列化来讲解,Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从...

    Java序列化和克隆

    2011-03-04 09:25 mojianpo JavaEye博客  我要评论(1) 字号: T |  T
    一键收藏,随时查看,分享好友!

    本篇文章主要对Java序列化来讲解,Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。

    AD:2013大数据全球技术峰会低价抢票中

    序列化

    Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。

    当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

    把Java对象转换为字节序列的过程称为对象的序列化。

    把字节序列恢复为Java对象的过程称为对象的反序列化。

    1、序列化的用途

    利用对象的序列化可以保存应用程序的当前工作状态,下次再启动的时候将自动地恢复到上次执行的状态。

    对象的序列化主要有两种用途:

    (a) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

    (b) 在网络上传送对象的字节序列。

    2、序列化的实现

    (1)JDK类库中的序列化API

    java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。

    java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

    只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。

    (2)对象序列化与反序列化的过程

    将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

    对象序列化包括如下步骤:

    (a)创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;

    (b)通过对象输出流的writeObject()方法写对象。

    对象反序列化的步骤如下:

    (a)创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;

    (b)通过对象输入流的readObject()方法读取对象。

    下面让我们来看一个对应的例子,类的内容如下:

    Java代码

       
    1. import java.io.*;     
    2. import java.util.Date;     
    3. public class ObjectSaver {     
    4.           public static void main(String[] args) throws Exception {     
    5.               ObjectOutputStream out = new ObjectOutputStream     
    6.                      (new FileOutputStream("D:""objectFile.obj"));     
    7.               //序列化对象     
    8.               Customer customer = new Customer("阿蜜果"24);     
    9.               out.writeObject("你好!");     
    10.               out.writeObject(new Date());     
    11.               out.writeObject(customer);     
    12.               out.writeInt(123); //写入基本类型数据     
    13.               out.close();     
    14.               //反序列化对象     
    15.               ObjectInputStream in = new ObjectInputStream     
    16.                      (new FileInputStream("D:""objectFile.obj"));     
    17.               System.out.println("obj1=" + (String) in.readObject());     
    18.               System.out.println("obj2=" + (Date) in.readObject());     
    19.               Customer obj3 = (Customer) in.readObject();     
    20.               System.out.println("obj3=" + obj3);     
    21.               int obj4 = in.readInt();     
    22.               System.out.println("obj4=" + obj4);     
    23.               in.close();     
    24.        }     
    25. }     
    26. class Customer implements Serializable {     
    27.        private String name;     
    28.        private int age;     
    29.        public Customer(String name, int age) {     
    30.               this.name = name;     
    31.               this.age = age;     
    32.        }     
    33.        public String toString() {     
    34.               return "name=" + name + ", age=" + age;     
    35.        }     
    36. }     
    37. import java.io.*;   
    38. import java.util.Date;   
    39. public class ObjectSaver {   
    40. public static void main(String[] args) throws Exception {   
    41. ObjectOutputStream out = new ObjectOutputStream   
    42. (new FileOutputStream("D:""objectFile.obj"));   
    43. //序列化对象   
    44. Customer customer = new Customer("阿蜜果"24);   
    45. out.writeObject("你好!");   
    46. out.writeObject(new Date());   
    47. out.writeObject(customer);   
    48. out.writeInt(123); //写入基本类型数据   
    49. out.close();   
    50. //反序列化对象   
    51. ObjectInputStream in = new ObjectInputStream   
    52. (new FileInputStream("D:""objectFile.obj"));   
    53. System.out.println("obj1=" + (String) in.readObject());   
    54. System.out.println("obj2=" + (Date) in.readObject());   
    55. Customer obj3 = (Customer) in.readObject();   
    56. System.out.println("obj3=" + obj3);   
    57. int obj4 = in.readInt();   
    58. System.out.println("obj4=" + obj4);   
    59. in.close();   
    60. }   
    61. }   
    62. class Customer implements Serializable {   
    63. private String name;   
    64. private int age;   
    65. public Customer(String name, int age) {   
    66. this.name = name;   
    67. this.age = age;   
    68. }   
    69. public String toString() {   
    70. return "name=" + name + ", age=" + age;   
    71. }   
    72. }   

    输出结果如下:

    Java代码

       
    1. obj1=你好!     
    2. obj2=Sat Sep 26 22:02:21 CST 2010     
    3. obj3=name=阿蜜果, age=24     
    4. obj4=123     
    5. obj1=你好!   
    6. obj2=Sat Sep 26 22:02:21 CST 2010   
    7. obj3=name=阿蜜果, age=24   
    8. obj4=123   

    因此例比较简单,在此不再详述。

    3、serialVersionUID作用:

    序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。

    有两种生成方式:

    一个是默认的1L,比如:

    Java代码

       
    1. private static final long serialVersionUID = 1L;     
    2. private static final long serialVersionUID = 1L;   

    一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:

    Java代码

       
    1. private static final   long      serialVersionUID = xxxxL;    
    2. private static final   long      serialVersionUID = xxxxL;   

    二、克隆

    有时想得到对象的一个复制品,该复制品的实体是原对象实体的克隆。复制品实体的变化不会引起原对象实体发生变化,这样的复制品称为原对象实体的克隆对象或简称克隆。

    1、浅复制(浅克隆)

    概念:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

    方法:类implements Cloneable,然后重写clone()方法,在clone()方法中调用super.clone()即可,没有其他操作了

    2、深复制(深克隆)

    概念:被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍

    方法:

    (1)类implements Cloneable,然后重写clone()方法,在clone()方法中调用super.clone(),然后还要对引用型变量所指的对象进行克隆。

    (2)序列化:将该对象写出到对象输出流,那么用对象输入流读回的对象就是原对象的一个深度克隆

    展开全文
  • 序列化克隆 → 推荐:《刀剑神域-序列之争》 序列化序列化 serialversionUID 作用 IDEA配置警告 序列化中常见的两类异常 java.io.NotSerializableException java.io.InvalidClassException 克隆克隆...

    序列化与克隆

    → 推荐:《刀剑神域-序列之争

    • 序列化
      • 序列化只保存类的属性信息
    • 反序列化
    • serialversionUID
      • 作用
      • IDEA配置警告
    • 序列化中常见的两类异常
      • java.io.NotSerializableException
      • java.io.InvalidClassException
    • 克隆
      • 浅克隆
      • 深克隆(序列化)
      • 序列化相关类的继承关系

    一:序列化

    在这里插入图片描述

    /**
     * 序列化指定Person对象
     * 		序列化只会保存原有类的属性;
     *
     * @param p 待序列化对象
     * @throws IOException
     */
    public static void serializePerson(Person p) throws IOException {
        // 创建文件夹和文件
        String personFileDirPath = System.getProperty("user.dir")+"\\person";
        File seriableFileDir = new File(personFileDirPath);
        if(!seriableFileDir.exists()){
            seriableFileDir.mkdir();
        }
        String personFilePath = System.getProperty("user.dir")+"\\person\\p1.person";
        File seriableFile = new File(personFilePath);
        if(!seriableFile.exists()){
            seriableFile.createNewFile();
        }
        if(p!=null){
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(personFilePath));
            oos.writeObject(p);
        }
    }
    

    二:反序列化

    /**
     *  根据文件反序列化指定对象
     *      序列化只会保存原有类的属性;
     *      反序列化时,只需要获得被序列化类的serialVersionUID+待获取属性+类名
     *          类名打开序列化文件第二行开头可以发现
     *
     * @param filePath 序列化对象文件
     * @return 反序列化后的对象
     */
    public static Person deSerializePerson(String filePath) throws IOException, ClassNotFoundException {
        if(filePath!=null||!filePath.trim().equals("")) {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
            return (Person) ois.readObject();
        }
        return null;
    }
    

    三:serialVersionUID

    在这里插入图片描述

    • 作用

    用于标记可序列化对象 (private static final long),对指定文件进行反序列化时需要验证源与目标具有相同的UID

    java.io.InvalidClassException: xyz.xx.Person; local class incompatible: stream classdesc serialVersionUID = 3437483674491733544, local class serialVersionUID = 2215763102943453354
    	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
    	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1939)
    	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1805)
    	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2096)
    	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1624)
    	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
    	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
    	at xyz.xx.Test.deSerializePerson(Test.java:60)
    	at xyz.xx.Test.main(Test.java:18)
    

    如果UID没有显示指明,类会自动根据当前类的信息摘要出一个serialVersionUID,当类的内容发生改变时,该默认生成的UID会发生很大的变化;

    • IDEA配置警告(未显式定义serialVersionUID时给与警告)

      在这里插入图片描述

    四:序列化中常见的两类异常

    • java.io.NotSerializableException

      被序列化的类没有实现Serializable接口

    • java.io.InvalidClassException

      反序列化对象UID与本地类UID不匹配

    五:克隆

    在这里插入图片描述

    • 实现Clonable接口

      • java.lang.CloneNotSupportedException
    • 重写Object类中的clone方法

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

    六:浅克隆与深克隆测试

    Person.java

    package xyz.xx;
    
    import java.io.Serializable;
    
    public class Person implements Serializable {
        private static final long serialVersionUID = 3437483674491733544L;
    
        private String name;
        private int age;
        private boolean gender;
    
        public Person(){}
    
        public Person(String name, int age, boolean gender) {
            this.name = name;
            this.age = age;
            this.gender = gender;
        }
    
        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;
        }
    
        public boolean isGender() {
            return gender;
        }
    
        public void setGender(boolean gender) {
            this.gender = gender;
        }
    }
    

    Student.java

    package xyz.xx;
    
    import java.io.Serializable;
    
    public class Student extends Person implements Serializable {
        private static final long serialVersionUID = -7461432514299767086L;
    
        private int score;
        public Student(){}
    
        public Student(String name, int age, boolean gender) {
            super(name, age, gender);
        }
    
        public int getScore() {
            return score;
        }
    
        public void setScore(int score) {
            this.score = score;
        }
    
        @Override
        public String toString() {
            return super.getName()+"-"+super.getAge()+"-"+(super.isGender()?"男":"女")+":"+score;
        }
    }
    

    Teacher.java

    内部使用序列化实现deepClone()

    package xyz.xx;
    
    import java.io.*;
    
    public class Teacher extends Person implements Cloneable, Serializable {
        private static final long serialVersionUID = -1883148076584384389L;
    
        private Student student;
    
        public Teacher(){}
    
        public Teacher(String name, int age, boolean gender, Student student) {
            super(name, age, gender);
            this.student = student;
        }
    
        public Student getStudent() {
            return student;
        }
    
        public void setStudentScore(int score) {
            this.student.setScore(score);
        }
    
        public Teacher deepClone() throws IOException, ClassNotFoundException {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            return (Teacher)ois.readObject();
        }
    
        @Override
        public String toString() {
            return super.getName()+"-"+super.getAge()+"-"+(super.isGender()?"男":"女")+":"+student;
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    

    Test.java

    package xyz.xx;
    
    /**
     * 下方两次获取逻辑不同,注意
     *
     *     false
     *     true
     *     学生A-18-女:99
     *     学生A-18-女:99
     *     false
     *     false
     *     学生A-18-女:199
     *     学生A-18-女:99
     */
    public class Test {
        public static void main(String[] args) {
            Student s1 = new Student("学生A",18,false);
            Teacher t1 = new Teacher("教师A",37,false,s1);
    
            try {
                Teacher t2 = (Teacher)t1.clone();
                System.out.println(t1==t2);
                // true
                System.out.println(t1.getStudent()==t2.getStudent());
                t1.setStudentScore(99);
                // 修改t1影响t1和t2
                System.out.println(t1.getStudent());
                System.out.println(t2.getStudent());
    
                Teacher t3 = t1.deepClone();
                System.out.println(t1==t3);
                // false
                System.out.println(t1.getStudent()==t3.getStudent());
                t1.setStudentScore(199);
                // 修改t1只影响t1
                System.out.println(t1.getStudent());
                System.out.println(t3.getStudent());
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    七:序列化相关类的继承关系

    在这里插入图片描述

    展开全文
  • 1、java序列化 序列化介绍: 序列化:将java对象写入字节流;反序列化:从字节流中恢复对象 意义:序列化机制允许将实现序列化的java对象装换位字节序列,这些字节序列可以保存在磁盘,数据库上,或者通过网络...
  • Java序列化克隆--对象深度拷贝

    千次阅读 2013-10-03 11:48:14
    Java序列化克隆--对象...Java序列化克隆 序列化   Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。   当两个进
  • Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。 当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种...
  • 一、序列化和反序列化的概念  把对象转换为字节序列的过程称为对象的序列化。  把字节序列恢复为对象的过程称为对象的反序列化。  对象的序列化主要有两种用途:  1) 把对象的字节序列永久地保存到硬盘上,通常...
  • Java序列化方式深克隆

    2018-01-18 08:48:38
    public static Object copyOfDeep(Object obj){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(obj);...
  • java 序列化和反序列化实现克隆

    千次阅读 2016-11-13 12:55:50
    package com.clone.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; pu
  • Serializable接口 序列化:对象的寿命通常随着生成...Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类...
  • java序列化深度克隆

    2011-08-18 09:24:36
    publicObject copy() throwsIOException, ... //将对象序列化后写在流里,因为写在流里面的对象是一份拷贝, //原对象仍然在JVM里 ByteArrayOutputStream bos = newByteArrayOutputStream(); ...
  • java通过对象序列化和反序列化实现克隆总结 在JAVA中,我们想要实现对一个对象的克隆主要有两种方式 实现Cloneable接口并重写clone()方法; 实现Serializable接口,然后通过对象的序列化和反序列化操作实现真正的...
  • Java 序列化方式实现深克隆

    千次阅读 2017-10-09 12:22:14
    // 用序列化与反序列化实现深克隆 private Object deepClone(Object src) { Object o = null; try { if (src != null) { ByteArrayOutputStream baos = new B
  • 序列化作用:  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;  2) 在网络上传送对象的字节序列。  在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便...
  • java 序列化实现深度克隆

    千次阅读 2015-01-29 10:16:47
    import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import j
  • java序列化与深度克隆

    2014-03-31 15:18:25
    如果类的成员变量比较复杂,例如引用了...可以考虑序列化的方法完成克隆 test代码 package com.mingrisoft; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.Fil
  • 本篇文章是对序列化存取实现java对象深度克隆的方法进行了详细的分析介绍,需要的朋友参考下
  • 在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走...这篇文章主要给大家介绍了Java中对象的序列化方式克隆,需要的朋友可以参考借鉴,下面来一起看看吧。
  • 利用序列化机制进行深拷贝: A.将对象序列化到输出流再读回即可,且中间过程无需写入文件,只需使用ByteArrayOutputStream将数据存为字节数组. *需要注意的是,这种克隆方法比显式地在clone方法中创建一个新的对象或...
  • serialVersionUID标识了序列化序列化时的版本 静态变量不会参与序列化 继承父类,父类不实现Serializable,则父类内的属性不参与序列化,即使父类内的属性是public或protected 使用transient关键字阻止序列化实例...
  • Java笔试面试-克隆序列化

    万次阅读 多人点赞 2019-09-15 22:44:59
    克隆 1.浅克隆 默认的 clone() 方法,为浅克隆,代码如下: class CloneTest { public static void main(String[] args) throws CloneNotSupportedException { Dog dog = new Dog(); dog.name = "旺财"; dog.ag....
  • 详细介绍了Java序列化流ObjectOutputStream、ByteArrayInputStream,内存操作流ByteArrayOutputStream、ByteArrayInputStream,以及实现深克隆
  • 使用Java序列化和反序列化可以实现信息的持久存储、或者也可以实现Java对象的深克隆。在前面文章讲解过使用序列化和反序列化来实现对象克隆,如下: Java之基础 - 深克隆与浅克隆(参见文章:...
  • Java序列化详解

    2019-09-10 11:26:06
    Java序列化和反序列化概述 序列化:把对象转换为字节序列的过程称为对象的序列化。 反序列化:把字节序列恢复为对象的过程称为对象的反序列化。 序列化的使用场景 1、把的内存中的对象持久化。如存到数据库或文件中...
  • Java序列化

    2015-07-18 10:06:18
    java序列化 序列化的作用 java序列化是把对象持久化, 将对象写入流或者文件中,以便网络传输远程对象,或者将对象的状态持久化。反序列化是将对象的状态读出重建承一个对象的过程。 序列化的必要性 java中一切都是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,763
精华内容 11,105
关键字:

java序列化克隆

java 订阅