java序列化与反序列化中transient和static成员剖析

在我的上一篇博文中讲解了一些基本的关于java序列化与反序列化的问题,现在我们一起来对对象中声明为transient和static的变量进行解析。

1:类中声明为transient变量

一旦类中某个变量声明为transient,则会告诉JVM,你不用帮我序列化该变量,我自己来进行序列化。将数据成员声明为transient后,序列化过程就无法将其加进对象字节流中,没有从transient数据成员发送的数据。后面数据反序列化时,要重建数据成员(因为它是类定义的一部分),但不包含任何数据,因为这个数据成员不向流中写入任何数据。记住,对象流不序列化。

还是上一篇博文代码,只是name属性中多加了个static,测试大妈如下:

package com.test;
import java.io.*;
public class Person implements Serializable {
    private static String name = "";//在这里和之前的有变动,多了个static
    public Person(){
        name = "高中同学都叫我ROBIN";
    }
    public Person(String name){
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    

    public static void main(String[] args) {
        Person person =new Person();
//File file = new File("H:\\test.txt");//建议用File.separator
        try {
            
            FileOutputStream fos = new FileOutputStream("test.out");//暂存内容

            ObjectOutputStream oos = new ObjectOutputStream(fos);

            System.out.println(" 1> " + person.getName());

            person.setName("我为自己代言!!!");                       

            oos.writeObject(person);

            oos.close();                       

    } catch (Exception ex) {  ex.printStackTrace();   }

    try {

            FileInputStream fis = new FileInputStream("test.out");

            ObjectInputStream ois = new ObjectInputStream(fis);

            person = (Person) ois.readObject();

            System.out.println(" 2> " + person.getName());

            ois.close();

    } catch (Exception ex) {

            ex.printStackTrace();

    }
    
    }

}

测试结果如下:

我上面不是说了吗static变量是不能狗被序列化的,按道理反序列化中调用getName方法输出结果应该也是和第一句话一样的啊!这到底是怎么了,难道我说的不对,看编译出的结果我也纳闷了,后来我在网上查了下,有一个答案解决了我的谜底:

那就是静态成员属于类级别的,所以不能序列化,这个之前我们都知道了。这里的不能序列化的意思,是序列化信息中不包含这个静态成员域为什么测试成功,是因为我是在同一个机器(而且是同一个进程),因为我的jvm已经把name变量加载进来了,所以我获取的是加载好的name,如果我把该变量传到另一台机器别的机器是不能狗得到后一个设置name值的,也就是图片中的第二个值而是两个值一样。

但也有些学过c++或则java的人会说,静态变量虽然术语类的,那为什么c++或则中还可以用对象.方法进行调用,虽然可以但程序还是会转换成进行类名.方法进行调用,而我序列化是序列化对象,所以跟说明了static不能狗被序列化缘由。

至于transient原理是和static一样的,就不多说了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值