黑马程序员技术交流社区

标题: 关于对象序列化 问题 [打印本页]

作者: 浪无痕-陈文坤    时间: 2013-8-11 11:32
标题: 关于对象序列化 问题
本帖最后由 浪无痕-陈文坤 于 2013-8-11 17:09 编辑

import java.io.*;

class ObjectStreamDemo
{
public static void main(String[] args) throws Exception
{
  writeObj();  //写的时候开这个
  readObj();   //  读的时候开这个
}
public static void readObj()throws Exception  // 读取
{
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
  // 和下面相对应 ,一般不存成.txt (因为里边的东西看不懂,打开没意义)存成 person.object

  Person p = (Person)ois.readObject();

  System.out.println(p);
  ois.close();
}

public static void writeObj()throws IOException
{
  ObjectOutputStream oos =    // 创建对象   将对象文件里边去  所以用 FileOutputStream
   new ObjectOutputStream(new FileOutputStream("obj.txt")); // 括号里边传字节流
//你要写的是一个对象,能直接操作对象的那个文件 Object   这些类出现都是在对更细节类进行操作。
  oos.writeObject(new Person("lisi0",399,"kr"));  //调用写入对象    存储到了硬盘上
      //  这个person在另一个类中有单独的定义
  oos.close();
}
}

class Person implements Serializable  //  如果不实现这个接口  会导致  上面的编译失败
{
  //给类定义标记用的     这就是实现Serializable接口
public static final long serialVersionUID = 42L;   //这个接口没有方法 (称为   标记接口)
//上面的uid标示是给编译器使用的  给一个固定标示  就是为了序列化方便(新的类还能去操作曾经被序列化的对象)
  //  uid   其实是根据你类中的那些成员算出来的。你类中无论成员变量还是成员函数都具备一个数字标示(数字签名)                                                 //   根据这些数字算出来这么一个号   来标示这个类
private String name;
int age;
// 若这里的private改变或不写  那个标记接口就起作用了
//transient int age;                //若不想将非静态的成员(age)序列化 这时加一个关键字修饰一下就可以了transient
//这时  age即使在堆内存当中  也不能被序列化 (保证其值在堆内存中存在而不在文本文件中存在)
static String country = "cn";  // 静态时不能被序列化的   读不出来
//静态在方法去里  而其他的在堆内存中(能把堆里边的序列化,却不能将其他地方的序列化)
Person(String name,int age,String country)
{
  this.name = name;
  this.age = age;
  this.country = country;
}
public String toString()
{
  return name+":"+age+":"+country;
}
}
1.红色部分都没注释结果:lisi0:399:kr
2.先注释readObject再注释writeObject结果:lisi0:399:cn
这是为什么?



作者: 神之梦    时间: 2013-8-11 16:08
这个貌似很蛋疼,这与jvm加载类时的一些内存存储数据有关
作者: 浪无痕-陈文坤    时间: 2013-8-11 16:24
本帖最后由 浪无痕-陈文坤 于 2013-8-11 17:07 编辑
神之梦 发表于 2013-8-11 16:08
这个貌似很蛋疼,这与jvm加载类时的一些内存存储数据有关

谢谢,我再想想!!哥们,又查了一下,明白了,

没new对象的时候country = “cn";
new 对象的时候对类变量(静态变量)赋值,那么此时的country="kr";在写入文件时它的值是”kr"而不是”cn",那么当都不注解的时候,readObject()时,由于country值不被序列化所以country=“kr".而先注释read运行再注注释write运行,此时static的值又被赋予country="cn"(由于country值不被序列化),所以输出的必是cn.

如果在第一种(都不注释)中写入对象后,再对static变量进行赋值为”cn",那么结果就会是“cn",而不会是”kr".
不容易呀,细节害死人



[size=144px]

作者: sergio    时间: 2013-8-11 18:35
这个static有点类似transient的关键字。
作者: 浪无痕-陈文坤    时间: 2013-8-11 19:21
sergio 发表于 2013-8-11 18:35
这个static有点类似transient的关键字。

不一样,一个是瞬态变量(瞬间被秒掉),一个是类成员(跟类相扶持),两者差距有点远,呵呵,谢谢!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2