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 Serialization API の秘密を発見する

于 2012-06-28T05:55:13.590 に答える
-2

反射を利用しています。プライベートとパブリックはセキュリティ対策ではありません。それはクラス利用者のみの契約です。

于 2012-06-28T05:45:46.713 に答える