精华内容
下载资源
问答
  • Java 对象的序列化

    2020-07-13 16:45:01
    对象序列化:将对象写到输出流中。 对象反序列化:从输入流中读取对象。 应用 调用远程方法:调用远程方法时,需要在客户机与服务器之间传递对象。 对象持久性保持:允许对象在创建他们生命周期结束后仍然保存,...

    概念

    对象序列化:将对象写到输出流中。
    对象反序列化:从输入流中读取对象。

    应用

    调用远程方法:调用远程方法时,需要在客户机与服务器之间传递对象。
    对象的持久性保持:允许对象在创建他们的生命周期结束后仍然保存,供以后程序调用。

    涉及的接口和类

    对象的序列化必须是:实现接口Serializable的类的对象。
    Serializable:是一个空接口,没有语义和字段,仅用于标识可序列化的语义。

    序列化的类和方法是:ObjectOutputStream,WriterObject。
    反序列化的类和方法是:ObjectInputStream,ReaderObject。

    展开全文
  • Java对象序列化研究

    2007-04-02 23:41:00
    Java对对象序列化的支持很简单,只要涉及的类和本类实现了java.io.Serializable接口,有一个serialVersionUID 就可以利用java.io.ObjectOutputStream进行对象的二进制格式输出了: package objOutPut;import ...

     

    Java对对象的序列化的支持很简单,只要涉及的类和本类实现了java.io.Serializable接口,有一个serialVersionUID 就可以利用java.io.ObjectOutputStream进行对象的二进制格式输出了:

    package objOutPut;

    import java.io.*;

    import java.util.Hashtable;
    import java.util.ArrayList;

    public class Canvas implements Serializable {
        
        
    private static final long serialVersionUID = -8391639048829504801L;

        
    public Hashtable htLabels = null;

        
    public ArrayList alLabels = null;

        
    public Canvas() {
            htLabels 
    = new Hashtable();
            alLabels 
    = new ArrayList();
        }


        
    public void toFile(String fileSpec) throws FileNotFoundException,
                IOException 
    {
            ObjectOutputStream os 
    = new ObjectOutputStream(new FileOutputStream(
                    fileSpec));
            os.writeObject(
    this);
        }


        
    public Canvas fromFile(String fileSpec) throws FileNotFoundException,
                IOException, ClassNotFoundException 
    {
            ObjectInputStream is 
    = new ObjectInputStream(new FileInputStream(
                    fileSpec));
            
    return (Canvas) is.readObject();

        }

    }

    现在问题是:在上述这个类里面,含有2个容器:Hashtable和ArrayList。如他们都同时保存了对象o(我们知道容器只是拷贝保存对象的指针),在序列化的时候,会不会把o存2次呢?感觉起来应该是只保存一次。可是不敢确定,于是验证了下:

    在同一个包里面,定义了一个Label类,他的实例会被放在上述容器中,

    package objOutPut;

    public class Label implements java.io.Serializable{
        
        
    private static final long serialVersionUID = -4343239993805802185L;
        
        
    public int id;
        
    public String name;
        
    public Point labelPoint;
        
    public Label(int id, String name, Point labelPoint){
            
    this.id = id; 
            
    this.name =name;
            
    this.labelPoint = labelPoint;        
        }

        
    public Label(int id, String name, double x, double y){
            
    this(id, name, new Point(x,y));        
        }

    }

    这里还用到了Point类,一个超级简单的类,又是超级有用的类:

    package objOutPut;

    public class Point implements java.io.Serializable {
        
        
    private static final long serialVersionUID = 6582745579823418928L;
        
    public double x;
        
    public double y;
        
    public Point(double x, double y){
            
    this.x = x;
            
    this.y = y;
        }

    }

    后面定义的2个类都是Serializable的,而且都有serialVersionUID。那么现在我们在Canvas里面加入Label类的实例,然后导出到文件,然后在导入,看内存地址指的对象是否还是同一个:

    在Canvas中加入main方法:

    public static void main(String[] argus) {
            Canvas c 
    = new Canvas();
            Label label1 
    = new Label(1"1"11);
            Label label2 
    = new Label(2"2"22);

            c.htLabels.put(
    "1", label1);
            c.htLabels.put(
    "2", label2);

            c.alLabels.add(label1);
            c.alLabels.add(label2);
            
    try {
                c.toFile(
    "C:/Canvas.out");
            }
     catch (FileNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
     catch (IOException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }

            
    try {
                Canvas cc 
    = c.fromFile("C:/Canvas.out");
                System.out.println(cc.htLabels.size());
            }
     catch (FileNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
     catch (IOException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }
     catch (ClassNotFoundException e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    在Eclipse3.2下设置断点,观察CC中Hashtable和ArrayList中保存的Label实例的内存ID,同时也观察他们包含的Point的内存ID。发现是一样的。

    结论:序列化时,即便容器包含2份对象指针,实际只会出现一个实例被序列化了。这个跟java容器本身保存对象指针是一致的。C++的Vector确是保存对象的拷贝了,而且是深拷贝。

    展开全文
  • 序列化与反序列化

    2020-10-21 10:33:09
    当我们想将内存中Java对象或者文件保存到硬盘中或者通过其他方式传输Java对象的时候,涉及序列化序列化 序列化简单来说,就是把对象转换为字节序列传输到硬盘文件过程称为对象的序列化。 反序列化序列...


    当我们想将内存中的Java对象或者文件保存到硬盘中或者通过其他方式传输Java对象的时候,涉及到序列化。


    序列化

    序列化简单来说,就是把对象转换为字节序列传输到硬盘文件的过程称为对象的序列化。


    反序列化

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


    如何实现序列化

    实现类实现Serializable接口。
    在这里插入图片描述
    Serializable接口是一个没有抽象方法和常量的接口。

    通常为了不影响序列化和反序列化,一般会在实现类里添加一条序列号。

    private static final long serialVersionUID =5l;//数字51是随意取的。
    
    展开全文
  • transient,中文翻译是短暂和对象序列化、反序列化有关。 一个只要实现了Serializable接口,则该实例就可以序列化,具体来说实例每个非静态成员变量都会序列化。注意是非静态成员变量,静态成员变量不会...

    transient,中文翻译是短暂的,和对象序列化、反序列化有关。

    一个类只要实现了Serializable接口,则该类实例就可以序列化,具体来说实例的每个非静态成员变量都会序列化。注意是非静态成员变量,静态成员变量不会序列化。但是假如某些字段涉及敏感信息,不能序列化存储到文件中或者经网络传输,则就应该用transient修饰。用transient修饰的变量在对象序列化时默认不会序列化,同时反序列化得到的对象中该变量值会是对应类型的默认值。

    代码示例:

    Address类:

    public class Address implements Serializable {
        private String nation;
        private String city;
        private String buildingNo;
    
        public String getNation() {
            return nation;
        }
    
        public void setNation(String nation) {
            this.nation = nation;
        }
    
        public String getCity() {
            return city;
        }
    
        public void setCity(String city) {
            this.city = city;
        }
    
        public String getBuildingNo() {
            return buildingNo;
        }
    
        public void setBuildingNo(String buildingNo) {
            this.buildingNo = buildingNo;
        }
    
        public Address() {
    
        }
    
        public Address(String nation, String city, String buildingNo) {
            this.nation = nation;
            this.city = city;
            this.buildingNo = buildingNo;
        }
    
        @Override
        public String toString() {
            return "Address{" +
                    "nation='" + nation + '\'' +
                    ", city='" + city + '\'' +
                    ", buildingNo='" + buildingNo + '\'' +
                    '}';
        }
    }

    Person类:

    public class Person implements Serializable {
        private String name;
        private Integer age;
        private Address address;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
    
        public Person(String name, Integer age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", address=" + address +
                    '}';
        }
    }

    测试类Test:

    public class Test {
        public static void main(String[] args) {
            String path = "d:/s.txt";
            try (OutputStream output = new FileOutputStream(path);
                 ObjectOutputStream oos = new ObjectOutputStream(output);
                 InputStream input = new FileInputStream(path);
                 ObjectInputStream ois = new ObjectInputStream(input)
            ) {
                oos.writeObject(new Person("zhangsan", 18, new Address("China", "Shenzhen", "FuTian")));
                Person person = (Person) ois.readObject();
                System.out.println(person);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    注意,上面说的是用transient修饰的变量在对象序列化时默认不会序列化,同时反序列化得到的对象中该变量值会是对应类型的默认值。注意,是默认,不是一定。因为是有办法让transient修饰的变量也参与序列化的。只需在类中加入两个方法即可:

    void writeObject(ObjectOutputStream oos) throws IOException;

    void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException;

    其中第一个是序列化方法,可以指定序列化的成员变量,第二个是反序列化方法,可以指定反序列化的成员变量。可以在这两个方法中显式指定被transient修饰的变量,这样该变量同样可以参与序列化和反序列化。

    代码示例:

    其他类代码不变,Person类:

    public class Person implements Serializable {
        private String name;
        private Integer age;
        private transient Address address;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        public Person(String name, Integer age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", address=" + address +
                    '}';
        }
    
        private void writeObject(ObjectOutputStream oos) throws IOException {
            oos.defaultWriteObject();
            oos.writeObject(address);
            System.out.println("person serialized");
        }
    
        private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
            ois.defaultReadObject();
            address = (Address) ois.readObject();
            System.out.println("person deserialized");
        }
    }

    上面代码中,标红的oos.defaultWriteObject(); 和 ois.defaultReadObject(); 是调用默认的序列化方法和反序列化方法去操作没有transient修饰的非静态成员变量(default方法能且仅能操作non-static、non-transient变量),之后用oos.writeObject(address); 和 address = (Address) ois.readObject(); 来显式指定address变量。这样,执行完Test类的main方法之后,同样可以打印出adderss信息,即使address用transient修饰了。

    Serializable接口还有个Externalizable子接口。该接口有2个方法:

    void writeExternal(ObjectOutput out) throws IOException;

    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;

    如果自定义类实现了Externalizable接口,则transient在该类中不起任何作用,属性能不能序列化和有没有transient修饰没有半毛钱关系。如果想序列化该类实例的某个属性,必须在writeExternal()方法中显式write,如果想反序列化时能够获取到属性值,必须在readExternal()显式read,且各属性write和read的顺序必须一样。如果writeExternal()方法和readExternal()方法中没有具体实现,则任何属性都不会序列化。

    代码示例:

    其他类不变,Person类:

    public class Person implements Externalizable {
        private String name;
        private Integer age;
        private transient Address address;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Address getAddress() {
            return address;
        }
    
        public void setAddress(Address address) {
            this.address = address;
        }
    
        public Person() {
        }
    
        public Person(String name, Integer age, Address address) {
            this.name = name;
            this.age = age;
            this.address = address;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", address=" + address +
                    '}';
        }
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeObject(name);
            out.writeObject(age);
            out.writeObject(address);
            System.out.println("person serialized");
        }
    
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            name = (String) in.readObject();
            age = (Integer) in.readObject();
            address = (Address) in.readObject();
            System.out.println("person deserialized");
        }
    }

    需要指出的是,假如想要通过反序列化来得到Externalizable实例,则Externalizable接口实现类必须要有无参构造器,否则会报java.io.InvalidClassException异常,因为在反序列化过程中,是先通过无参构造器创造出对象,然后调用各属性的setter给属性设置值的。

    同时需要指出的是,假如一个类没有实现Serializable接口或者Externalizable接口,则在序列化该类实例时会报java.io.NotSerializableException异常。更进一步,假如该类没有被transient修饰的非静态成员变量所属类型没有实现Serializable接口或者Externalizable接口,则在序列化时也会报java.io.NotSerializableException异常。

    转载于:https://www.cnblogs.com/koushr/p/5873397.html

    展开全文
  • 关于序列化与反序列化,主要涉及有以下知识点: ...序列化时使用是ObjectOutputStream类的writeObject方法;而反序列化时使用是ObjectInputStream中readObject方法。 Serializable接口用于表示某个...
  • 在面向对象的编程中,都会涉及序列化和序列化,像java中,有一个接口Serializable,用来实现java序列化,php中也有Serializable方法来实现php序列化。这里我写了一个java的序列化。 下面是一个student,为实现...
  • 使用序列化流实现对List深拷贝 深拷贝 为新的对象重新开辟一个内存空间,拷贝原有对象的数据结构值;新的对象的值修改不会涉及对象的值(请注意性能问题)。 实现序列化拷贝条件 实体对象实现...
  • 本小节会简要概括JavaIO中序列化以及涉及流,主要包括ObjectInputStreamObjectOutputStream。 Serializable 原文链接 如果你希望能够序列化反序列化,必须实现Serializable接口,就像所...对象序列化本...
  • 在java中,实体是一个非常重要概念,我们可以在实体中封装对象、设置其属性方法等。关于实体,也经常涉及到适配器模式、装饰者模式等设计模式。那么在实际代码开发中,关于实体类的注意事项有哪些呢? ...
  • 前提:这个实体必须实现java.io.Serializable这个接口类。 实体最下面有三个重写方法toString 、equals、 hashCode,如何理解为什么都要重写这三个方法? 这些就涉及到业务上操作。 首先,toString是将...
  • 序列化是一个比较纠结东西,而java中涉及序列化接口又分为SerializableExternalizable。 区别为Serializable使用是默认序列化行为算法,而当你需要自己来控制序列化行为时,使用Externalizable。 当一个...
  • ObjectOutputStreamObjectInputStream类   这两个流是用来将对象写入到文件中,或者从文件中读取一个对象,都是高级流。...实现序列化和序列化的要求是:该对象对应的类,必须实现序列化接口(实现序列化...
  • REST接口开发核心

    2019-11-25 20:58:33
    REST接口开发核心任务 RestAPI开发核心工作 在开发REST API接口时,视图中做...在以上操作中,涉及到两个概念:序列化和序列化序列化 将程序中一个数据结构类型转换为其他格式(字典、JSON、XML等),...
  • 注意:基于序列化和序列化实现克隆不仅仅是深度克隆,更重要是通过泛型限定,可以检查出要克隆的对象是否支持序列化,这项检查是编译器完成,不是在运行时抛出异常,这种是方案明显优于使用Object类的clone...
  • 对序列化的基础知识不够了解的朋友可以参考以下几篇文章:Java对象的序列化与反序列化深入分析Java的序列化与反序列化单例与序列化的那些事儿在这几篇文章中,我分别介绍过了序列化涉及的类和...
  • JavaIO流,万物皆文件

    2021-06-10 06:36:10
    引入IO的原因 基本概念: 数据源流的概念 IO流的概念细分 IO流的体系 IO流在Java中的流对象:inputStream .... ... 3 序列化涉及的接口和类  4 序列化的反序列化的使用 IO的其他常用: File, RandomAccessFile ...
  • java常用整理

    2020-07-12 19:07:28
    1.java,lang.Appendable能够被追加char序列和的对象。如果某个类的实例打算接收来自Formatter格式输出,那么该必须实现Appendable接口。 2.Comparable接口,里面只有唯一待实现方法compareTo,在调用...
  • C语言接口与实现 c语言

    热门讨论 2010-10-07 11:18:41
    语言,但是它要求程序员对像c一样语言有更多驾驭能力更高警惕性,因为这语言很容易破坏带有隐含实现信息的接口,反之亦然。 然而一但掌握了基于接口的设计方法,就能够在服务于众多应用程序通用接口...
  • java-IO(三)

    2020-07-01 21:35:41
    目录java IO序列化和反序列化序列化涉及的类和接口装饰器模式IO中流的装饰器Apache IOUtils和FileUtils总结 java IO 继续上一篇内容 序列化和反序列化 当两个进程远程通信时,彼此可以发送各种类型的数据。 无论是何...
  • 这个对象就可以被序列化,java这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个实现了Serilizable接口,这个类的所有属性方法都会自动序列化。 然而在实际开发过程中,我们...
  • 原型模式有很多好处 :创建比较复杂的对象,无需考虑过程,简化了创建对象的...但是一定要注意,涉及每个都需要序列化接口以及实现cloneable接口 所以这也算原型模式一个缺点,而且深克隆化代码也会复杂 ...
  • Spring HttpInvoker远程调用例子

    千次阅读 2013-12-12 16:49:47
    HttpInvoker的实现原理java的RMI实现原理相同,都是基于Http协议,将java对象序列化以后以流的方式在客户端服务器端进行传输。 例子的项目结构图:   执行流程图如下: 类图如下: 涉及的类接口: ...
  • java transient关键字

    2020-11-09 14:40:08
    这个对象就可以被序列化,java这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个实现了Serilizable接口,这个类的所有属性方法都会自动序列化。 然而在实际开发过程中,我们...
  • JAVA transient关键字

    2020-07-16 09:39:40
    这个对象就可以被序列化,java这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个实现了Serilizable接口,这个类的所有属性方法都会自动序列化。 然而在实际开发过程中,我们...
  • 这个对象就可以被序列化,java这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个实现了Serilizable接口,这个类的所有属性方法都会自动序列化。 然而在实际开发过程中,...
  • 这个对象就可以被序列化,java这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个实现了Serilizable接口,这个类的所有属性方法都会自动序列化。 然而在实际开发过程中,...
  • 引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。 21、heapstack有什么区别。  栈是一种线形集合,其添加删除元素的操作应在同一段完成。栈按照后进先出的...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 127
精华内容 50
关键字:

对象序列化涉及的类和接口