`
yejienihao
  • 浏览: 2448 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

请教一个对象序列化问题:哪些field在序列化时会被写入stream中?

阅读更多
在查看java.io.ObjectOutputStream.writeObject(Object obj)方法的注释时,看到这句说明

Write the specified object to the ObjectOutputStream. The class of the object, the signature of the class, and the values of the non-transient and non-static fields of the class and all of its supertypes are written.

大致意思是:
将指定的对象写入到ObjectOutputStream中。有关这个对象的类的信息、类的签名、该类的非transient和非static的属性的值,以及该对象所有的父类都被写入ObjectOutputStream。

按照这个说明,non-static属性的值不会被写入,但在下面的例子中,static属性的值是被写入了的。

我想,这个应该是注释说明的错误吧?请教一下各位。


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Foo implements Serializable {
	private String name = "My name is foo.";
	private static String desc = "I will still be here!";
	private transient String abandoned = "I will be abandoned!";
	
	public Foo(){}
	
	public String toString(){
		StringBuilder result = new StringBuilder();
		result.append(name);
		result.append("-");
		result.append(desc);
		result.append("-");
		result.append(abandoned);
		return result.toString();
	}
	
	public static void main(String[] args) throws ClassNotFoundException, IOException{
		Foo foo = new Foo();
		System.out.println("foo = " + foo);
		
		ObjectOutputStream out = new ObjectOutputStream(
				new FileOutputStream("foo.out"));
		out.writeObject("Foo storage\n");
		out.writeObject(foo);
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(
				new FileInputStream("foo.out"));
		String s = (String)in.readObject();
		Foo foo2 = (Foo)in.readObject();
		System.out.println(s + "foo2 = " + foo2);
		in.close();		
	}
}



输出结果:
foo = My name is foo.-I will still be here!-I will be abandoned!
foo2 = My name is foo.-I will still be here!-null


分享到:
评论
4 楼 yejienihao 2008-12-12  
<p><br/>to whmily:
我这里执行了结果两次desc的还是一样的。
</p>
<p> </p>
<p>
对JDK中的注释重新理解:
注释没有错,因为static的属性不是和对象相关的,而是包括在类中。因为序列化的时候类的相关信息也写入,所以static属性的值也包括在其中了。</p>
3 楼 whmily 2008-12-12  
<p>先在main中执行如下代码</p>
<pre name='code' class='java'>         Foo foo = new Foo(); 
         <strong>Foo.desc = "Will write static value?";</strong>
         System.out.println("foo = " + foo); 
          
         ObjectOutputStream out = new ObjectOutputStream( 
                 new FileOutputStream("foo.out")); 
         out.writeObject("Foo storage\n"); 
         out.writeObject(foo); 
         out.close(); 
</pre>
<p><br/>再在main中执行如下代码</p>
<pre name='code' class='java'>         ObjectInputStream in = new ObjectInputStream( 
                 new FileInputStream("foo.out")); 
         String s = (String)in.readObject(); 
         Foo foo2 = (Foo)in.readObject(); 
         System.out.println(s + "foo2 = " + foo2); 
         in.close();
</pre>
<p><br/>楼主看看两次输入的desc值还一样吗?<br/></p>
<p> </p>
2 楼 yejienihao 2008-12-12  
icyiwh 写道

&nbsp; 并不是在序列化的时候把static内容写入了文件,而是在反序列化还原出一个对象的时候,你使用的static内容根本就不属于这个对象,而是这个class.
&nbsp; 所以,即使序列化没有把static内容写入文件,你反序列化还原对象的时候也可以引入.

&nbsp; 另外,你不应该在同一个JVM上去测试,而且static的内容不要在初始化的时候给它赋值,而是通过setter给它赋值.


对了,static内容是属于class,而不是object的。谢谢指点:)
1 楼 icyiwh 2008-12-12  
  并不是在序列化的时候把static内容写入了文件,而是在反序列化还原出一个对象的时候,你使用的static内容根本就不属于这个对象,而是这个class.
  所以,即使序列化没有把static内容写入文件,你反序列化还原对象的时候也可以引入.

  另外,你不应该在同一个JVM上去测试,而且static的内容不要在初始化的时候给它赋值,而是通过setter给它赋值.

相关推荐

    05.C# 知识回顾 - 序列化.pdf

    在C#中,如果一个类对象被序列化时引用了另一个类的实例,而该被引用的类同样具有SerializableAttribute属性,那么在序列化过程中,这个被引用的类的实例也会被自动序列化。 以一个具体的示例来说明序列化的应用: ...

    轉Serializable至Stream

    在某些场景下,如在JSP(JavaServer Pages)中,我们可能需要将一个`Serializable`对象转化为`Stream`,以便直接发送到客户端。以下是关于如何实现这个过程的详细解释。 首先,让我们理解`Serializable`接口。任何...

    详解protobuf-c之在C语言中如何使用repeated生成数组和字符串(包含配置pb-callback-t)

    protobuf-c是Google Protocol Buffers(protobuf)在C语言中的实现,它允许你在C代码中方便地序列化和反序列化结构化数据。本篇文章将详细解释如何在C语言环境中使用protobuf-c处理`repeated`字段,创建数组和字符串...

    Java反射、IO流.pdf

    Java反射是Java编程语言中的一个强大特性,允许在运行时检查类、接口、字段和方法的信息,甚至可以动态地创建对象并调用方法。通过Java.lang.reflect包中的类,如Class、Constructor、Field和Method,我们可以实现对...

    delphi 流读写格式化记录文件

    在Delphi编程中,流(Stream)是一种处理数据的强大工具,它可以用来读取、写入和存储各种类型的数据。在本篇文章中,我们将深入探讨如何使用Delphi的流技术来读写格式化记录文件,这涉及到对文件的操作,数据序列化...

    dom4j和反射的例子,源码

    在Java编程中,DOM4J和反射是两个非常重要的技术,它们在处理XML文档和对象操作方面发挥着关键作用。...这些技术在实际开发中非常实用,例如在配置文件处理、数据序列化和反序列化、动态加载类等方面都有广泛的应用。

    C++常用英语单词.pdf

    3. **累加(accumulating)**:在编程中,累加通常指连续添加数值到一个变量中,例如在循环中。 4. **实际变元/参数(actual argument/parameter)**:在函数调用时,传递给函数的值称为实际参数。 5. **地址运算符...

    笔记2232 真的非常不错

    首先,数据被发送到一个分片,然后经过一系列步骤,如文档的路由、序列化、持久化等,最终存储到磁盘。 2. **HashMap的put操作**:HashMap的put操作通过哈希函数计算键的哈希值,进行二次扰动以减少冲突,如果发生...

    java开发常用的jar包的作用解释.pdf

    * SerializationUtils:用于处理对象序列化,提供比一般 Java 序列化更高级的处理能力。 * StringEscapeUtils:用于正确处理转义字符,产生正确的 Java、JavaScript、HTML、XML 和 SQL 代码。 * StringUtils:处理 ...

    (完整版)C++必备专业英语单词(已标注音标).docx

    45. **析构函数(Destructor)**:在对象生命周期结束时自动调用的函数,用于清理资源。 46. **文档编写(Documentation)**:记录代码和系统设计的详细信息,以便其他人理解和维护。 47. **双精度数(Double-...

    c++专业英语单词.docx

    43. **Default Copy Constructor**:缺省复制构造函数,当没有定义自己的复制构造函数时,编译器会自动生成一个。 44. **Default Constructor**:缺省构造函数,无参数的构造函数,用于初始化类的实例。 45. **...

    java面试题(较全面)

    - **包装类与基本类型的转换:** Java提供了基本类型的包装类如`Integer`, `Short`, `Long`, `Byte`, `Float`, `Double`, `Character`, `Boolean`,这些包装类可以用来在对象和基本类型之间进行转换。 - **示例代码...

    C# 解析二进制文件程序

    结构体的实例可以直接序列化到二进制流中: ```csharp [StructLayout(LayoutKind.Sequential)] public struct MyStruct { public int Field1; public string Field2; } MyStruct data; // 填充数据... using (var ...

    KETTLE 节点使用说明

    每当作业运行时,会增加一个计数器的值。这对于跟踪作业执行的次数非常有帮助。 #### 十二、序列生成器(Sequence Generator) 生成一系列的唯一标识符,通常用于为新创建的记录分配唯一的 ID。这对于确保数据集中...

    XILINX DDR3 IP核使用教程完整版

    在仿真过程中,理解DDR3的命令和地址总线协议至关重要,包括行地址、列地址、Bank地址的序列,以及预充电、激活、写入、读取等操作。 **二、综合** 综合是将高级语言描述的硬件设计转化为逻辑门级表示的过程。在...

Global site tag (gtag.js) - Google Analytics