18

I have a question on serialization. If my class has private variables and there are no getters and setters, then how will the value of these variables be read by the Serialization API.

1
  • I am waiting for a better answer. Shall accept one after some time. Thanks.
    – Sid
    Commented Nov 22, 2010 at 12:26

4 Answers 4

14

First, access permissions are the compile-time feature. the access is not controlled in runtime.

It may confuse you but try to do the following: create 2 versions of class A:

1

public class A {
    public foo() {
        System.out.println("hello");
    }
}

2

public class A {
    private foo() {
        System.out.println("hello");
    }
}

Now write class that calls new A().foo() and compile it with the first version of the class A. Then put the second version into classpath and run the application. It will work!

So, do not worry about the access permissions: they can always be bypassed.

If for instance you are using reflection to call private method foo() from you have to get the method and then call setAccessible(true):

Method m = A.class.getMethod("foo",
null); m.setAccessible(true);
m.invoke(new A(), null);

If we can access private methods from our code, be sure that JDK classes can do this even if they are written in java. BTW as far as I know standard java serialization is implemented as native code.

1
  • 2
    Huh? If I'm not totally mistaken, the first part is just wrong. If you access a private method/field you get a IllegalAccessError at runtime. This is a requirement of the JVMS (see section 5.4.3). Running your test confirms this.
    – musiKk
    Commented Nov 23, 2010 at 9:20
13

The Serialization API doesn't worry about private variables. Its purpose is to convert your object to a binary representation in a file or some other kind of storage that can be reconstructed later.

Here is Java's serialization algorithm explained.

14
  • But it does need to read the values, right? And the API is written in Java, so there must be a way it reads the private variables.
    – Sid
    Commented Nov 22, 2010 at 12:22
  • 2
    @SidCool: Reflection and serialization are performed during runtime. Encapsulation is more of a design thing.
    – darioo
    Commented Nov 22, 2010 at 12:32
  • 3
    So how do you think you can see the values of private variables in debugger.
    – jutky
    Commented Nov 22, 2010 at 12:38
  • 3
    Declaring a variable private doesn't actually secure it in any way. It can still be read if you can get access to the memory location it's stored in, or read from the serialised file. If you don't want this to happen (e.g. with a password) mark the variable with the transient keyword (so it won't be serialised) or only hold it in an encrypted form in the field (java.security.* has classes you can use for this - Google can undoubtedly provide a tutorial).
    – Scott
    Commented Nov 22, 2010 at 12:40
  • 1
    Yes, you can do it. Again you can do it in the debugger.
    – jutky
    Commented Nov 22, 2010 at 12:43
6

The default serialization mechanism doesn't care about the access scope of member variables. In other words public, protected, package-private, and private variables are all treated in the same way. The implementation details might vary, but as I remember the Sun JRE does this by implementing much of the serialization in native (JNI) code where access privileges aren't enforced.

1
  • 1
    Most of the serialization code is in Java, however the field accessing does use JNI as you say. Commented Nov 22, 2010 at 13:24
4

Don't wory, by using the reflection anyone can access your's private fields.

Here is an example how to do this.

2
  • Does that not compromise encapsulation?
    – Sid
    Commented Nov 22, 2010 at 12:30
  • What's the problem with encapsulation? I'm not sure I understand the question.
    – jutky
    Commented Nov 22, 2010 at 12:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.