1

当我运行这个演示时,它调用 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();
        }
    }
}
4

3 回答 3

5

如果您的可序列化对象有任何 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);
}
于 2012-06-28T06:26:16.213 回答
1

虚拟机将自动检查是否在相应的方法调用期间声明了任一方法。虚拟机可以随时调用您的类的私有方法,但没有其他对象可以。因此,类的完整性得到维护,序列化协议可以继续正常工作。序列化协议始终以相同的方式使用,即调用 ObjectOutputStream.writeObject() 或 ObjectInputStream.readObject()。因此,即使提供了那些专门的私有方法,对象序列化的工作方式与任何调用对象都相同。

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

发现 Java 序列化 API 的秘密

于 2012-06-28T05:55:13.590 回答
-2

它使用反射。私人和公共不是安全措施。那只是类用户的合同。

于 2012-06-28T05:45:46.713 回答