瞬态字段的Java序列化

瞬态字段的Java序列化,java,serialization,reflection,Java,Serialization,Reflection,我正在阅读《Java第四版思考》。 这里描述了一种奇怪的瞬态字段序列化方法: import java.io.*; public class SerializationTest implements Serializable { private String firstData; //transient field, shouldn't be serialized. transient private String secondData; public Seri

我正在阅读《Java第四版思考》。 这里描述了一种奇怪的
瞬态
字段序列化方法:

import java.io.*;

public class SerializationTest implements Serializable {
    private String firstData;
    //transient field, shouldn't be serialized.
    transient private String secondData;

    public SerializationTest(String firstData, String test2) {
        this.firstData = firstData;
        this.secondData = test2;
    }

    /**
     * Private method, same signature as in Serializable interface
     *
     * @param stream
     * @throws IOException
     */
    private void writeObject(ObjectOutputStream stream) throws IOException {
        stream.defaultWriteObject();
        stream.writeObject(secondData);
    }

    /**
     * Private method, same signature as in Serializable interface
     *
     * @param stream
     * @throws IOException
     */
    private void readObject(ObjectInputStream stream)
            throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        secondData = (String) stream.readObject();

    }

    @Override
    public String toString() {
        return "SerializationTest{" +
                "firstData='" + firstData + '\'' +
                ", secondData='" + secondData + '\'' +
                '}';
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream("object.out");
            oos = new ObjectOutputStream(fos);
            SerializationTest sTest = new SerializationTest("First Data", "Second data");
            oos.writeObject(sTest);
        } finally {
            oos.close();
            fos.close();
        }
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream("object.out");
            ois = new ObjectInputStream(fis);
            SerializationTest sTest = (SerializationTest) ois.readObject();
            System.out.println(sTest);
        } finally {
            ois.close();
            fis.close();
        }
        //Output:
        //SerializationTest{firstData='First Data', secondData='Second data'}
    }
}
如您所见,有实现的私有方法
writeObject
readObject

问题是:

ObjectOutputStream和ObjectInputStream使用反射访问私有方法的原因是什么


Java中包含了多少这样的后门?

呃,它不是“后门”。。。您实现了一个自定义序列化,在调用忽略临时字段的默认序列化后,将临时字段输出到输出流

呃,这不是“后门”。。。您实现了一个自定义序列化,在调用忽略临时字段的默认序列化后,将临时字段输出到输出流

后门?它一直在规范中。这是实现对象非默认序列化的唯一方法

非默认序列化使您处于序列化驱动程序的位置。您可以将任何内容写入输出流,只要能够读回并在流的另一端构造对象,就可以了


此人决定序列化瞬态字段这一事实并不是问题所在,关键是如果您正在实现自己的序列化方案,您可以做任何您想做的事情。

后门?它一直在规范中。这是实现对象非默认序列化的唯一方法

非默认序列化使您处于序列化驱动程序的位置。您可以将任何内容写入输出流,只要能够读回并在流的另一端构造对象,就可以了


此人决定序列化临时字段这一事实并不是问题所在,关键是如果您正在实现自己的序列化方案,您可以做任何您想做的事情。

可序列化接口是标记接口。所以它就像一个标签来解释java编译器。还有其他标记接口,如Clonable等。有关更多信息,请参阅。
但是现在使用的更多的是days@annotations。

可序列化的接口是marker接口。所以它就像一个标签来解释java编译器。还有其他标记接口,如Clonable等。有关更多信息,请参阅。
然而,现在a days@annotations的使用越来越多。

不是后门,而是顺便说一句,您的资源处理没有正确完成。标准形式是:
Resource=acquire();尝试{use(resource);}最后{resource.release();}
。您应该为每个资源单独执行此操作。在JavaSE6中,在大多数情况下,您可以编写
try(Resource=acquire()){use(Resource);}
。无需关闭对象流,只需在愉快的情况下刷新
ObjectOutputStream
(也就是说在
try
的主体中;在
最后
中刷新也会在错误情况下完成,这不是您真正想要的)。@Tom{语法已经在JavaSE6中了?这对我来说是新的,我以为它只有7个。@Paŭlo Ebermann Typo.应该是“在JavaSE7中”。(而且您不应该使用
-target 1.6-source 1.7
。除了目标必须至少与源代码一样最新的规则外,还需要额外的库支持。可能Retroweaver或类似工具会破解一些东西。)不是后门,但顺便说一句,您的资源处理没有正确完成。标准形式是:
resource-resource=acquire();try{use(resource);}最后{resource.release();}
。您应该为每个资源单独执行此操作。在Java SE 6中,您可以编写
try(resource-resource=acquire()){use(resource);}
在大多数情况下。无需关闭对象流,只需在愉快的情况下刷新
ObjectOutputStream
(也就是说在
try
的主体中;最后在
中刷新
也会在错误情况下关闭对象流,这不是您真正想要的)。@Tom:the
try(…){
语法已经在JavaSE6中了?这对我来说是新的,我以为它只有7个。@Paŭlo Ebermann Typo.应该是“在JavaSE7中”。(而且您不应该使用
-target 1.6-source 1.7
。除了目标必须至少与源代码一样最新的规则外,还需要额外的库支持。可能Retroweaver或类似工具会破解一些东西。)