transient、Externalizable

Java transient关键字使用小结

1、transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。
2、被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化。
3、一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量一样被初始化。

如下面的例子

package com.kkoolerter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class Main implements Serializable {

private static final long serialVersionUID = -5836283489677344417L;
    private transient int classValue = 10;
    private transient Date date = new Date();
    private transient static int staticValue = 10;

public static void main(String[] args) throws Exception {
        Main m = new Main();
        m.classValue = 11;
        Main.staticValue = 11;
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
                new File("0xjh000")));
        out.writeObject(m);

out.close();

ObjectInputStream in = new ObjectInputStream(new FileInputStream(
                new File("0xjh000")));
        Main m1 = (Main) in.readObject();
        in.close();

System.out.println(m1.classValue);
        System.out.println((m1.date == null ? "date is null"
                : "date is not null"));
    }

}

程序将输出:
0
date is null

这就说明了一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。

思考一下下面的例子:
package com.kkoolerter;

import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class ExternalizableTest implements Externalizable {

private transient String content = "哈哈~我将会被序列化,不管我是是否被transient关键字修饰";

@Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(content);
    }

@Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        content = (String) in.readObject();
    }

public static void main(String[] args) throws Exception {
        ExternalizableTest et = new ExternalizableTest();
        ObjectOutput out = new ObjectOutputStream(new FileOutputStream(
                new File("ext0000")));
        out.writeObject(et);

ObjectInput in = new ObjectInputStream(new FileInputStream(new File(
                "ext0000")));
        ExternalizableTest et1 = (ExternalizableTest) in.readObject();
        System.out.println(et1.content);

out.close();
        in.close();
    }
}

程序运行后将输出如下结果:
哈哈~我将会被序列化,不管我是是否被transient关键字修饰

这是为什么呢,不是说类的变量被transient关键字修饰以后将不能序列化了吗?
我们知道在Java中,对象的序列化可以通过实现两种接口来实现,若操作的是一个Serializable对象,则所有的序列化将会自动进行,若操作的是 一个Externalizable对象,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。因此第二个例子输出的是变量content初始化的内容,而不是null。

转自:http://www.cnblogs.com/liuling/archive/2013/05/05/transient.html

时间: 2024-12-25 16:26:43

transient、Externalizable的相关文章

Hibernate JPA中@Transient、@JsonIgnoreProperties、@JsonIgnore、@JsonFormat、@JsonSerialize等注解解释

@jsonignore的作用作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响. http://www.cnblogs.com/toSeeMyDream/p/4437858.html 当表间有One2Many或Many2One时,会发生无限循环的场景,如何破? 只要在Set方法前增加以下注解即可: @JsonIgnore public Set xxxs() { return this.xxxYyyy; } http://www.cnblogs.com/tomp

transient、volatile关键字

transient是在对象序列化的时候,不参与序列化的字段. 如LinkedList实现了Serializable,其中有变量transient int size = 0; 在Serializable序列化的时候size时不会参与序列化的,如用ObjectOutputStream读取LinkedList时,size时不会被写入到流中的,包括json转换. package com.ada.wuliu.mobile.front.action.test; import java.io.Serializ

hibernate中对象的三种状态:Transient、Persistent和Detached

1 public class ThreeState { 2 public static void main(String[] args) { 3 User u = new User(); //属性:id(对应数据库递增字段),name,age 4 u.setName("cbirdq"); 5 u.setAge(20); 6 //堆内存有u,session缓存没有u,数据库没有u,没有id 7 8 Session session = sessionFactory.getCurrentSe

深入理解net core中的依赖注入、Singleton、Scoped、Transient(四)

相关文章: 深入理解net core中的依赖注入.Singleton.Scoped.Transient(一) 深入理解net core中的依赖注入.Singleton.Scoped.Transient(二) 深入理解net core中的依赖注入.Singleton.Scoped.Transient(三) 一.什么是依赖注入(Denpendency Injection) 这也是个老身常谈的问题,到底依赖注入是什么? 为什么要用它? 初学者特别容易对控制反转IOC(Iversion of Contr

JavaScript系列二:变量、数组、流程控制、函数以及事件响应

JavaScript入门内容的复习:JavaScript入门 输出内容 document.write("xxx"); 弹出警告窗口 alert("xxx"); 弹出确认窗口 confirm("xxx"); 弹出提问窗口 prompt("xxx"); 单行注释 // 多行注释 /* */ 函数语法格式 function xxx() { xxxx; } 引入JS外部文件的方式 <script src="xx.js&

Hibernate中对象的3种状态:瞬时态、持久态、脱管态

Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久 态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object).1.瞬时态由new命令开辟内存空间的java对象, 比如:ThinkSoar thinkSoar = new ThinkSoar(“name”, “边哥”); 如果没有变量对该对象进行引用,它将被java虚拟机回收. 瞬 时对象在内存孤

【Java】基础:常见修饰符(权限修饰符以及abstract、static、final等)与变量的描述

1. 修饰符 public.protected.private.default abstract.static.final. abstract:抽象类.抽象方法 static:静态变量.静态方法.静态代码块 final修饰类.方法.变量 transient.violatile.native.synchronized 2. 变量 实例变量.局部变量.类变量 1. 修饰符 · public.protected. private.default 修饰类时的访问权限   当前类 同包 子孙类 其它包 p

python 之 前端开发( JavaScript变量、数据类型、内置对象、运算符、流程控制、函数)

11.4 JavaScript 11.41 变量 1.声明变量的语法 // 1. 先声明后定义 var name; // 声明变量时无需指定类型,变量name可以接受任意类型 name= "egon"; ? // 2. 声明立刻定义 var age = 18; 2.变量名命名规范 1.由字母.数字.下划线.$ 组成,但是不能数字开头,也不能纯数字2.严格区分大小写3.不能包含关键字和保留字(以后升级版本要用的关键字).如: abstract.boolean.byte.char.clas

0101 JavaScript标识符、关键字、保留字

10.1 标识符 标识(zhi)符:就是指开发人员为变量.属性.函数.参数取的名字. 标识符不能是关键字或保留字. 10.2 关键字 关键字:是指 JS本身已经使用了的字,不能再用它们充当变量名.方法名. 包括:break.case.catch.continue.default.delete.do.else.finally.for.function.if.in.instanceof.new.return.switch.this.throw.try.typeof.var.void.while.wi