`

Java序列化机制要序列化那些内容

    博客分类:
  • Java
阅读更多
在javaeye上搜到一篇robbin关于java序列化的回复,我觉得其中的例子很有说服力,转过来和大家分享。
      关于更多java序列化的问题可以参见JAVA系列之对象的序列化与反序列化
      Java的序列化机制只序列化对象的属性值,而不会去序列化什么所谓的方法。其实这个问题简单思考一下就可以搞清楚,方法是不带状态的,就是一些指令,指令是不需要序列化的,只要你的JVM classloader可以load到这个类,那么类方法指令自然就可以获得。序列化真正需要保存的只是对象属性的值,和对象的类型。

我们可以做一个简单的小试验,来证实一下:
package com.javaeye;

import java.io.Serializable;

public class DomainObject  implements Serializable {

	private String name;
	
	private int age ;

	public int getAge() {
		return age;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name){
		this.name = name;
	}
	
	
}
package com.javaeye;     
     
import java.io.Serializable;     
     
public class DomainObject  implements Serializable {     
     
    private String name;     
         
    private int age ;     
     
    public int getAge() {     
        return age;     
    }     
     
    public void setAge(int age) {     
        this.age = age;     
    }     
     
    public String getName() {     
        return name;     
    }     
     
    public void setName(String name) {     
        this.name = name;     
    }     
         
         
}    
 package com.javaeye;  
   
 import java.io.Serializable;  
   
 public class DomainObject  implements Serializable {  
   
     private String name;  
       
     private int age ;  
   
     public int getAge(){  
         return age;  
     }  
   
     public void setAge(int age) {  
         this.age = age;  
     }  
   
     public String getName(){  
         return name;  
     }  
   
     public void setName(String name); {  
         this.name = name;  
     }  
       
       
 }   

package com.javaeye;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Main {

	public static void main(String[] args); throws Exception {
		DomainObject obj = new DomainObject();;
		obj.setAge(29);;
		obj.setName("fankai");;
		FileOutputStream fos = new FileOutputStream("DomainObject");;
		ObjectOutputStream oos = new ObjectOutputStream(fos);;
		oos.writeObject(obj);
		oos.close();
		fos.close();
	}

}view plaincopy to clipboardprint?
package com.javaeye;     
     
import java.io.FileOutputStream;     
import java.io.ObjectOutputStream;     
     
public class Main {     
     
    public static void main(String[] args); throws Exception {     
        DomainObject obj = new DomainObject();;     
        obj.setAge(29);;     
        obj.setName("fankai");;     
        FileOutputStream fos = new FileOutputStream("DomainObject");     
        ObjectOutputStream oos = new ObjectOutputStream(fos);;     
        oos.writeObject(obj);     
        oos.close();    
        fos.close();     
    }     
     
}   
 package com.javaeye;  
   
 import java.io.FileOutputStream;  
 import java.io.ObjectOutputStream;  
   
 public class Main {  
   
     public static void main(String[] args); throws Exception {  
         DomainObject obj = new DomainObject();;  
         obj.setAge(29);;  
         obj.setName("fankai"); 
         FileOutputStream fos = new FileOutputStream("DomainObject");  
         ObjectOutputStream oos = new ObjectOutputStream(fos);  
         oos.writeObject(obj);
         oos.close(); 
         fos.close();
     }  
   
 }  
    
   DomainObject是我们准备序列化的类,在Main里面,我们new一个DomainObject的对象,然后赋值,最后把该对象序列化到一个硬盘文件中。然后使用一种支持二进制编辑器,例如UltraEdit打开这个文件,看看Java都对DomainObject序列化了哪些信息,你就什么都明白了。

为了更方便观察,我使用Linux下面的strings去提取文本信息,输出为:
robbin@linux:~> strings DomainObject
com.javaeye.DomainObject
ageL
namet
Ljava/lang/String;xp
fankai
这些信息很直观的告诉我们序列化都保存了些什么内容:
1)对象的类型
2)对象属性的类型
3)对象属性的值

并没有什么方法签名的信息,更不要说什么序列化方法了。
然后我们再做一个试验,给DomainObject增加两个方法:
package com.javaeye;

import java.io.Serializable;

public class DomainObject  implements Serializable {

	private String name;
	
	private int age ;

	public int getAge(); {
		return age;
	}

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

	public String getName(); {
		return name;
	}

	public void setName(String name); {
		this.name = name;
	}
	
	public String toString(); {
		return "This is a serializable test!";
	}
	
	public void doSomeWork(); {
		System.out.println("hello");;
	}
}
package com.javaeye;     
     
import java.io.Serializable;     
     
public class DomainObject  implements Serializable {     
     
    private String name;     
         
    private int age ;     
     
    public int getAge(); {     
        return age;     
    }     
     
    public void setAge(int age); {     
        this.age = age;     
    }     
     
    public String getName(); {     
        return name;     
    }     
     
    public void setName(String name); {     
        this.name = name;     
    }     
         
    public String toString(); {     
        return "This is a serializable test!";     
    }     
         
    public void doSomeWork(); {     
        System.out.println("hello");;     
    }     
}     
 package com.javaeye;  
   
 import java.io.Serializable;  
   
 public class DomainObject  implements Serializable {  
   
     private String name;  
       
     private int age ;  
   
     public int getAge(); {  
         return age;  
     }  
   
     public void setAge(int age); {  
         this.age = age;  
     }  
   
     public String getName(); {  
         return name;  
     }  
   
     public void setName(String name); {  
         this.name = name;  
     }  
       
     public String toString(); {  
         return "This is a serializable test!";  
     }  
       
     public void doSomeWork(); {  
         System.out.println("hello");;  
     }  
 }    
    
   我们增加了toString方法和doSomeWork方法,按照你的理论,如果序列化方法的话,产生的文件体积必然增大。记录一下文件体积,92Byte,好了,删除,运行程序,生成了新的文件,看一下体积,还是92Byte!

拿到Linux下面再提取一下字符串:
robbin@linux:~> strings DomainObject
com.javaeye.DomainObject
ageL
namet
Ljava/lang/String;xp
fankai
完全一模一样!

然后我们再做第三个试验,这次把DomainObject的两个属性以及相关方法删除掉:
package com.javaeye;

import java.io.Serializable;

public class DomainObject  implements Serializable {

	public String toString(); {
		return "This is a serializable test!";
	}
	
	public void doSomeWork(); {
		System.out.println("hello");;
	}
}
package com.javaeye;     
     
import java.io.Serializable;     
     
public class DomainObject  implements Serializable {     
     
    public String toString(); {     
        return "This is a serializable test!";     
    }     
         
    public void doSomeWork(); {     
        System.out.println("hello");;     
    }     
}    
 package com.javaeye;  
   
 import java.io.Serializable;  
   
 public class DomainObject  implements Serializable {  
   
     public String toString(); {  
         return "This is a serializable test!";  
     }  
       
     public void doSomeWork(); {  
         System.out.println("hello");;  
     }  
 }   

修改Main类如下:
package com.javaeye;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class Main {

	public static void main(String[] args); throws Exception {
		DomainObject obj = new DomainObject();;

		FileOutputStream fos = new FileOutputStream("DomainObject");;
		ObjectOutputStream oos = new ObjectOutputStream(fos);;
		oos.writeObject(obj);;
		oos.close();;
		fos.close();;
	}

}
package com.javaeye;     
     
import java.io.FileOutputStream;     
import java.io.ObjectOutputStream;     
     
public class Main {     
     
    public static void main(String[] args); throws Exception {     
        DomainObject obj = new DomainObject();;     
     
        FileOutputStream fos = new FileOutputStream("DomainObject");;     
        ObjectOutputStream oos = new ObjectOutputStream(fos);;     
        oos.writeObject(obj);;     
        oos.close();;     
        fos.close();;     
    }     
     
}    
 package com.javaeye;  
   
 import java.io.FileOutputStream;  
 import java.io.ObjectOutputStream;  
   
 public class Main {  
   
     public static void main(String[] args); throws Exception {  
         DomainObject obj = new DomainObject();;  
   
         FileOutputStream fos = new FileOutputStream("DomainObject");;  
         ObjectOutputStream oos = new ObjectOutputStream(fos);;  
         oos.writeObject(obj);;  
         oos.close();;  
         fos.close();;  
     }  
   
 }   

      按照你的理论,如果序列化方法的话,我们必然应该在文件里面发现方法的签名信息,甚至方法里面包含的字符串,好了,再运行一遍,然后打开看一下吧!文件现在体积变成了45Byte,拿到Linux下面提取一下信息:
robbin@linux:~> strings DomainObject
com.javaeye.DomainObject
只有对象的类型信息,再无其它东西了!

      请记住序列化机制只保存对象的类型信息,属性的类型信息和属性值,和方法没有什么关系,你就是给这个类增加10000个方法,序列化内容也不会增加任何东西,不要想当然的臆测自己不了解的知识,动手去做!

原文:http://blog.csdn.net/ilibaba/archive/2009/03/10/3975680.aspx


另外可以参考这个
http://www.ibm.com/developerworks/cn/java/j-lo-serial/index.html?ca=drs-
分享到:
评论

相关推荐

    java序列化和反序列化的方法

    Java 序列化和反序列化是 Java 语言中的一种机制,用于将对象转换为字节流,以便在网络上传输或存储。序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。 在 Java 中,序列化和反序列化是...

    Java序列化_Java序列化结构_

    Java序列化是Java平台中的一种持久化机制,它允许对象的状态被转换成字节流,以便存储、网络传输或在不同时间点恢复。这个过程被称为序列化,而反向操作称为反序列化。序列化在许多场景下都非常有用,比如在分布式...

    Java序列化的机制和原理

    Java序列化是Java平台提供的一种将对象转换为字节流,以便存储、在网络上传输或者在后续时间重新创建相同对象的机制。这是Java编程中一个非常重要的概念,尤其是在分布式环境和持久化存储中。让我们深入探讨一下Java...

    Java序列化

    - Java序列化是Java平台提供的一种持久化机制,它允许将对象转换为字节序列,这样就可以保存在文件中或在网络上传输。 - 序列化不仅可以用来持久化数据,还可以用于进程间通信(IPC)和远程方法调用(RMI)。 2. ...

    Protocol Buffer序列化对比Java序列化.

    Protocol Buffer(简称PB)是Google开发的一种高效的数据序列化协议,而Java序列化是Java平台内置的一种序列化机制。两者的主要目标都是将对象转化为字节数组,便于在网络传输、持久化存储等场景中使用。然而,它们...

    java序列化全解

    Java序列化是Java平台中的一种核心机制,它允许对象的状态被转换成字节流,以便存储到磁盘、数据库,或者在网络中进行传输。这对于实现持久化、远程方法调用(RMI)以及Enterprise JavaBeans(EJB)等高级功能至关...

    java 序列化时排除指定属性

    Java序列化是Java平台提供的一种持久化机制,它允许我们将一个Java对象转换为字节流,以便存储到磁盘上,或者通过网络进行传输。这使得我们可以保存和恢复对象的状态。实现序列化的类需要实现`Serializable`接口,...

    C#和Java的序列化反序列化

    本篇文章将深入探讨C#和Java中的序列化与反序列化机制。 首先,我们要了解什么是序列化。序列化是指将对象的状态转化为可存储或可传输的数据格式的过程。这个过程通常将内存中的对象转换成字节流,以便保存到磁盘、...

    java序列化实现演示

    在给定的链接"Java序列化机制(2)- serialVersionUID 实验"中,博主通过一个实验详细解释了`serialVersionUID`的作用和重要性。实验可能包括以下步骤: 1. 创建一个实现`Serializable`接口的简单类,并运行序列化...

    java 序列化代码示例

    Java序列化是Java平台中的一种标准机制,它允许将对象的状态转换为字节流,以便存储、传输或恢复。在Java中,一个类如果要实现序列化,需要实现`Serializable`接口,这是一个标记接口,不包含任何方法。下面我们将...

    java序列化原理与算法

    首先,我们需要创建一个实现了`Serializable`接口的类`TestSerial`,这样Java序列化机制才能处理这个类的对象。 接下来,我们编写代码将对象序列化并输出为字节流,存储在一个临时文件`temp.out`中。 ```java ...

    java序列化(Serializable)的作用和反序列化

    ### Java序列化(Serializable)的作用与反序列化详解 #### 一、序列化是什么? 序列化是指将程序中的对象转换为字节流的过程,从而方便存储或传输这些对象。通常,序列化用于将对象的状态(即其实例变量的值,而非...

    java serializable 序列化与反序列化

    **一、Java序列化** 1. **什么是序列化**:序列化是将对象的状态(属性和成员变量)转换为可以存储或传输的数据格式的过程。在Java中,通常是将对象转换为字节数组,以便写入磁盘或通过网络发送。 2. **为什么需要...

    Java对象序列化标准最新版

    ### Java对象序列化标准知识点详解 #### 一、系统架构概览 **1.1 概览** Java 对象序列化是一种将Java对象的...以上内容涵盖了Java序列化标准的关键知识点,深入了解这些概念有助于更好地理解和应用Java序列化技术。

    Java_序列化的高级认识

    序列化ID,即`serialVersionUID`,是Java序列化机制中一个关键的概念。它是一个类的唯一标识符,用于在序列化和反序列化过程中确定类的版本一致性。如果序列化对象和反序列化对象的`serialVersionUID`不匹配,将会抛...

    java序列化和反序列化

    序列化机制使得Java对象能够在不同的平台之间进行传输,并且能够保持其原始状态。 **特点:** - **跨平台兼容性:** 序列化后的对象可以在不同的操作系统之间传输,无需担心数据格式或内存布局的不同。 - **对象...

    java 常用序列化和反序列化框架使用demo

    然而,Java标准库提供的序列化机制效率较低且安全性欠佳,因此出现了许多第三方框架来优化这一过程。本篇将介绍几个常用的Java序列化和反序列化框架,并通过示例代码进行演示。 1. **Java标准序列化**: Java标准...

    FST:快速Java序列化的替代品

    **FST:快速Java序列化的替代方案** 在Java开发中,序列化是一个常见的需求,它允许将对象的状态转换为字节流,以便于存储或网络传输。标准的Java序列化虽然方便,但在处理大量数据时,性能往往成为瓶颈。这时,FST...

    java序列化之protobuf

    Java序列化是将Java对象转换为字节流的过程,以便可以在网络上传输或存储在磁盘上。这使得数据能够跨不同的系统平台进行传输和持久化。Protocol Buffers(protobuf)是Google推出的一种高效、跨平台的数据序列化协议...

Global site tag (gtag.js) - Google Analytics