2

When i run this demo it's call TestBean's writeObject method which is private

How is it possible ?

Here is the Code:

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();
        }
    }
}
MaVRoSCy
  • 17,747
  • 15
  • 82
  • 125
chetan
  • 3,175
  • 20
  • 72
  • 113

3 Answers3

7

If your serializable object has any writeObject method, it will be called otherwise the defaultWriteObject method will be called.

The private method calling is possible using the reflection. If you see the source code of ObjectOutputStream Class in that method writeSerialData, the code below answers your question.

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);
}
Syam
  • 1,202
  • 11
  • 23
2

The virtual machine will automatically check to see if either method is declared during the corresponding method call. The virtual machine can call private methods of your class whenever it wants but no other objects can. Thus, the integrity of the class is maintained and the serialization protocol can continue to work as normal. The serialization protocol is always used the same way, by calling either ObjectOutputStream.writeObject() or ObjectInputStream.readObject(). So, even though those specialized private methods are provided, the object serialization works the same way as far as any calling object is concerned.

You will get more about from this article:

Discover the secrets of the Java Serialization API

jmiserez
  • 2,991
  • 1
  • 23
  • 34
UVM
  • 9,776
  • 6
  • 41
  • 66
-2

It uses reflection. private and public are not security measures. That is only a contract for class users.

Fakrudeen
  • 5,778
  • 7
  • 44
  • 70
  • Incorrect. They are security measures that can be overridden via Reflection by code that has permission to do so. – user207421 Jun 28 '12 at 11:01
  • @EJP. I don't think they are. It is not like say public key encryption which you can't work around. To me they define the contract of what is usable by class consumers and what is internal implementation detail. Please see http://stackoverflow.com/questions/8357469/how-can-i-protect-my-private-funcs-against-reflection-executing – Fakrudeen Jun 29 '12 at 06:27