ObjectOutputStream的对象如何调用Serializable对象的私有writeObject方法

时间:2012-06-28 05:35:48

标签: java serialization

当我运行此演示时,它调用TestBean的writeObject方法是私有的

怎么可能?

以下是代码:

import java.io.FileOutputStream;

public class Test {

    public static void main(String[] args) {

        try {
            TestBean testBean = test.new TestBean();

            testBean.setSize(23);
            testBean.setWidth(167);

            FileOutputStream fos =
                new FileOutputStream(new File("d:\\serial.txt"));
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(testBean);

            oos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class TestBean implements Serializable {

        private static final long serialVersionUID = 1L;

        private int size;
        private int width;

        public int getSize() {
            return size;
        }

        public void setSize(int size) {
            this.size = size;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        private void writeObject(ObjectOutputStream out) throws IOException {
            System.out.println("TestBean writeObject");
            out.defaultWriteObject();
        }

        private void readObject(ObjectInputStream input) throws IOException,
                                                                ClassNotFoundException {
            System.out.println("TestBean readObject ===================> ");
            input.defaultReadObject();
        }
    }
}

3 个答案:

答案 0 :(得分:4)

如果您的可序列化对象具有任何writeObject方法,则将调用它,否则将调用defaultWriteObject方法。

使用反射可以调用私有方法。如果在该方法writeSerialData中看到ObjectOutputStream类的源代码,则下面的代码将回答您的问题。

if (slotDesc.hasWriteObjectMethod()) {
 // through reflection it will call the Serializable objects writeObject method
} else {
// the below is the same method called by defaultWriteObject method also.
writeSerialData(obj, desc);
}

答案 1 :(得分:0)

  

虚拟机会自动检查是否有任何一种方法   在相应的方法调用期间声明。虚拟机   可以随时调用你班级的私人方法而不是其他方法   对象可以。因此,保持了班级的完整性   序列化协议可以继续正常工作。该   序列化协议总是以相同的方式使用,通过调用   ObjectOutputStream.writeObject()或ObjectInputStream.readObject()。   因此,即使提供了那些专门的私人方法,   对象序列化的工作方式与任何调用对象相同   关心。

您将从本文中获得更多信息:

Discover the secrets of the Java Serialization API

答案 2 :(得分:-2)

它使用反射。私人和公众不是安全措施。这只是班级用户的合同。