黑马程序员技术交流社区
标题:
ObjectOutputStream流中关于静态成员不能被序列化
[打印本页]
作者:
铁血丹心
时间:
2014-6-6 23:09
标题:
ObjectOutputStream流中关于静态成员不能被序列化
我百度到的题目,我运行试了一下,也看不懂结果为什么?
第一种情况:先把readObj()注释掉,写入以后,再先把writer注释掉,然后再把readObj方法打开
writeObj();
//readObj();
然后再
//writeObj();
readObj();
输出结果:lisi--0--CN
第二种情况:两个都不注释同时运行
writeObj();
readObj();
输出结果:lisi--0--KR
输出结果为啥不一样???
第二种情况下,statci的 country 属性咋就变了呢
package io.inputoutput;
import java.io.*;
class Person implements Serializable {
public static final long serialVersionUID = 42L;
String name;
transient int age; // 加 transient 关键字后的属性也不能被序列化
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;
}
}
public class ObjStream01 {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
writeObj();
readObj();
}
public static void writeObj() throws IOException { // 写入对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
"F:\\A\\123.txt"));
oos.writeObject(new Person("lisi", 19, "KR"));
oos.close();
}
public static void readObj() throws IOException, ClassNotFoundException { // 读取对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
"F:\\A\\123.txt"));
Person p = (Person) ois.readObject();
System.out.println(p);
ois.close();
}
}
复制代码
作者:
彭飞
时间:
2014-6-7 00:29
本帖最后由 彭飞 于 2014-6-7 07:42 编辑
哥们:
情况是这个样子了。
首先明确,【静态变量是不能被序列化】的 但是为什么有发生了如此困惑的局面呢?
两个方法: 写、读。
writeObj();
readObj();
当单独写入后,再读取的时候 结果为:lisi--0--CN ,情况正确、正常。
而两个方法同时运行时,结果为:lisi--0--KR , 情况正确、正常。
哥们可能要杀人了。 哈哈。 原理在于内存中。
内存中有,栈、堆、方法区。 静态变量在方法区中,都知道。
当两个方法单独运行时,首先写入一个 new Person(1,2,3);>>>> 2和3,不被序列号,所以都变成了0和null 然后 toString()时,country 指向的是 cn
所以最后读取方法时,打印的结果是 cn。
而当 两个方都法运行时,按逻辑,应该也是一样的,执行写入完毕,读取。 但是问题来了,
同样是执行上面的步奏,当读的时候,
这个时候,写入的KR在内存中并没有立马消失,被 read 方法所识别,而read 方法中最先有的是 静态 country = cn ,
这个时候 就发生了,指向新的地址,最终序列化的时候变为了null,但toString 的时候就是 KR 了,
个人理解的是,首先我们走入了一个误区,昨夜久久不能入睡,忽然想到 老毕讲awt 用udp 实现在同一个 cmd 进行发送和读取信息
读写本不应该在一个线程中完成, 一个人自己说话的同时朗读,很容易产生混乱,搞不清的局面,
而线程正好就解决了这一问题,
好比哥们有俩电话,正在接电话的时候,另一电话又有妹纸找,哥们我接,跟这个妹纸说的时候,把另外的电话放远点,对吧,
一个人跟两个人说不着边际话,没问题。这也就是为什么 需要线程的缘故,
当然,这些都是我的推断。 这里有段小代码,仅供参考:
package com.awt;
import java.io.*;//Serializable;
public class Test3 {
static String country = "CNn";//[1]、在方法区中就把地址给改变了。
public static void main(String [] args){
String name = "a";
int age = 1;
//String country = "CNnttttt";//[2]、这个是编外,说明静态修饰 是优先初始化,但是 String 的特性没变。
per p = new per(name,age,country);
System.out.println(p);
}
}
class per{
String name;
transient int age;
static String country = "CN";
per(String name, int age, String country) {
this.name = name;
this.age = age;
this.country = country;
}
public String toString() {
return name + "--" + age + "--" + country;
}
}
复制代码
牵扯到以下三个问题:1、序列化问题 2、静态修饰问题 3、String特性问题 4、线程问题
作者:
谭荣强
时间:
2014-6-8 05:04
oos.writeObject(new Person("lisi", 19, "KR"));已经将country改成“KR(棒子!)”
两个方法不注释:
Proson类在内存中没有消失。当读取一个Person的实例对象时,静态被对象共享。所以打印KR.
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2