`

反序列化时恢复transient字段

    博客分类:
  • java
阅读更多
我们知道将字段设置为transient,可以避免该自动被序列化,但若反序列化时又希望该transient有值怎么办呢?
一种不使用transient的办法是使用Externalizable接口。Serializable接口默认序列化所有字段,而Externalizable接口继承自Serializable,要求实现两个方法readExternal(ObjectInput),writeExternal(ObjectOutput),默认不序列化任何字段,字段需要显式序列化。
显然transient只能和Serializable接口共用,在Serializable类中反序列化时恢复transient的值。可以通过在类中添加
private void readObject(ObjectInputStream ois);
private void writeObject(ObjectOutputStream oos);
两个方法。注:方法必须为private,此方法也非Serializable接口中的方法,但在序列化和反序列化时会自动被调用(很特殊吧)。
完整例子如下
 
public class TestSerializable {
    public static void main(String[] args) {
        String url = "jdbc:oracle:thin:@10.141.245.123:1521:FDU";
        Properties prop = new Properties();
        prop.setProperty("user", "system");
        prop.setProperty("password", "fducs");
        SerialObject serialObj = new SerialObject(url,prop);
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new java.io.File("SerialObject.out")));
            oos.writeObject(serialObj);
        } catch (IOException ex) {
            Logger.getLogger(TestSerializable.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("SerialObject original:\n"+ serialObj);
        SerialObject backObj = null;
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new java.io.File("SerialObject.out")));
            backObj = (SerialObject) ois.readObject();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(TestSerializable.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(TestSerializable.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("SerialObject target:\n"+ backObj);
    }
}
class SerialObject implements java.io.Serializable {
    private String url;
    private Properties prop;
    private transient Connection con;
    public SerialObject(String url, Properties prop) {
        this.url = url;
        this.prop = prop;
        con = getConnection(url, prop);
    }
    private Connection getConnection(String url, Properties prop) {
        Connection connect = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            connect = DriverManager.getConnection(url, prop);
        } catch (SQLException ex) {
            Logger.getLogger(TestSerializable.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(TestSerializable.class.getName()).log(Level.SEVERE, null, ex);
        }
        return connect;
    }
    @Override
    public String toString(){
        StringBuffer sbuf = new StringBuffer();
        sbuf.append("URL="+url);
        sbuf.append("\n");
        sbuf.append("Properties="+prop);
        sbuf.append("\n");
        sbuf.append("Connection="+con);
        return sbuf.toString();
    }
    private void readObject(ObjectInputStream ois){
        try {
            ois.defaultReadObject();
            System.out.println("url="+url);
            System.out.println("prop="+prop);
            con = getConnection(url,prop);
        } catch (IOException ex) {
            Logger.getLogger(SerialObject.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(SerialObject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    private void writeObject(ObjectOutputStream oos){
        try {
            oos.defaultWriteObject();
        } catch (IOException ex) {
            Logger.getLogger(SerialObject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
分享到:
评论

相关推荐

    java 对象的序列化与反序列化

    4. **非序列化字段**:有些字段可能不希望被序列化,可以使用`transient`关键字标记。这些字段在序列化过程中会被忽略。 5. **深拷贝与浅拷贝**:序列化实际上是实现了深拷贝,即创建了对象的一个完全独立的副本,...

    java serializable 序列化与反序列化

    3. **注意事项**:反序列化时,必须确保类定义和序列化时完全一致,包括类名、包名以及所有字段。否则,会抛出`InvalidClassException`。 **三、序列化版本ID (`serialVersionUID`)** Java允许我们定义一个名为`...

    java对象序列化和反序列化

    - 非公开(private)成员变量也会被序列化,如果不想序列化某些字段,可以使用`transient`关键字。 - 序列化可能导致安全问题,如对象的敏感信息暴露,需谨慎处理。 **二、Java反序列化** 1. **定义**:Java反...

    JAVA对象的序列化与反序列化详细PPT课件.pptx

    反序列化时,也会按照默认方式恢复这些变量。若同时定义了`writeObject(ObjectOutputStream out)`和`readObject(ObjectInputStream in)`方法,那么在序列化和反序列化时会优先使用这些自定义的方法。 如果类实现了`...

    java 序列化时排除指定属性

    - **设计考虑**:某些属性可能包含临时或计算值,在反序列化时不需要恢复。 3. **如何排除特定属性?** Java序列化默认会序列化对象的所有属性,但可以通过以下两种方式排除指定属性: - **使用`transient`...

    对象的序列化和反序列化

    对象的序列化和反序列化是Java编程语言中重要的概念,它们主要用于持久化对象的状态,以便在需要时能够恢复。序列化是将一个对象转换为字节流的过程,而反序列化则是将字节流还原为原来的对象。这两个过程在许多场景...

    Java中的序列化与反序列化.pdf

    此外,如果一个类包含不希望被序列化的字段,可以通过添加`transient`关键字来标记这些字段,它们将不会被包含在序列化过程中。 另外,Java还提供了一个更灵活的序列化接口`Externalizable`,它要求类自己控制序列...

    Java对象的序列化和反序列化实践

    2. **私有字段**:序列化默认会序列化所有非静态、非transient字段。若不想某些字段被序列化,可以添加`transient`关键字。 3. **性能**:序列化和反序列化可能影响性能,尤其是在处理大量对象时。因此,应谨慎使用...

    Java对象的序列化与反序列化Java开发Java经验技巧

    - **用途**:Java提供了`transient`关键字,用于标记类的某个字段不参与序列化和反序列化。 - **应用场景**:例如,某些字段可能包含敏感信息,不适合在网络上传输,或者字段的值可以通过其他方式重新计算得到。 ...

    java序列化与反序列化

    序列化和反序列化可能会消耗大量资源,特别是在处理大量数据时。为了提高效率,可以考虑使用更高效的序列化库,如Google的Protocol Buffers、Apache Thrift或JSON-B。 总结: Java序列化和反序列化是Java平台中的...

    java序列化和反序列化1

    在Java中,序列化是将一个对象转换为字节序列的过程,而反序列化则是将字节序列恢复为原始对象的过程。 1. **序列化的目的** - **持久化存储**:将对象的状态保存到磁盘,以便在程序后续运行或重启后重新加载。 -...

    java 对象默认序列化的干预方法

    // 反序列化除transient字段外的所有其他字段 age = in.readInt(); // 从输入流中读取并设置age字段 } // ... } ``` 在这个例子中,`writeObject()`方法首先调用`defaultWriteObject()`来序列化非`transient`...

    序列化和反序列化1

    在Java编程语言中,序列化和反序列化是两种重要的技术,它们允许对象的状态被转换成字节序列以便存储或在网络...通过自定义序列化和反序列化方法,我们可以更好地控制对象的存储和恢复过程,确保数据的一致性和安全性。

    JAVA对象的序列化与反序列化详细PPT学习教案.pptx

    在反序列化时,也会根据这些字段的状态进行恢复。 2. 如果类除了实现`Serializable`接口外,还自定义了`writeObject(ObjectOutputStream out)`和`readObject(ObjectInputStream in)`方法,那么在序列化和反序列化...

    Java序列化与反序列化

    反序列化时,必须确保类的定义与序列化时完全相同,包括类名、字段名和类型,否则可能会抛出`InvalidClassException`等异常。 除了基本的序列化,Java还提供了更高级的功能,如`transient`关键字,它可以用于标记...

    什么是Java的序列化和反序列化?如何实现对象的序列化和反序列化?(java面试题附答案).txt

    - 标记为`transient`的字段不会参与序列化过程。 - 这对于保护敏感信息非常有用,比如密码等。 4. **serialVersionUID**: - 序列化版本标识符,用于保证序列化和反序列化的对象的一致性。 - 如果对象结构发生...

    03-03-02-序列化和反序列化1

    因为序列化可以暴露对象的内部状态,所以不应该对包含敏感信息的对象进行序列化,除非采取了适当的保护措施,如使用`transient`关键字标记不应序列化的字段,或者自定义序列化和反序列化逻辑。 对于基于Socket的...

    java中的序列号和反序列化.doc

    1. 实现`Serializable`接口但不定义`readObject`和`writeObject`方法:在这种情况下,JDK会默认处理对象的序列化和反序列化,将对象的非`transient`和非`static`字段转换成字节流。这是最简单的方法,适用于大多数...

Global site tag (gtag.js) - Google Analytics