Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Effective java Item no 74(on serialization): Implement Serializable judiciously

It item no 74 of effective java book there is a paragraph (2nd para from last of the item 74) which mentions as per below:

Inner classes (Item 22) should not implement Serializable. They use compiler-generated synthetic fields to store references to enclosing instances and to store values of local variables from enclosing scopes. How these fields correspond to the class definition is unspecified, as are the names of anonymous and local classes. Therefore, the default serialized form of an inner class is ill- defined.

I know about inner class uses compiler generated synthetic field to store reference to enclosing instances e.g. if the enclosing class is MyEnclosing and inner class is MyInner then the enclosing reference is MyEnclosing.this. But i am not able to get the BOLD part. Please help me getting the meaning. Thanks!!!

like image 964
Trying Avatar asked Mar 21 '13 20:03

Trying


People also ask

What does implements Serializable do in Java?

To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java. io.

What is serialization and Serializable in Java?

Serialization in Java is the process of converting the Java code Object into a Byte Stream, to transfer the Object Code from one Java Virtual machine to another and recreate it using the process of Deserialization.

What happens if we implement Serializable interface in Java?

If a super class implements Serializable, then its sub classes do automatically. When an instance of a serializable class is deserialized, the constructor doesn't run. If a super class doesn't implement Serializable, then when a subclass object is deserialized, the super class constructor will run.

How do I prevent some data from getting serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.


2 Answers

Suppose you have a local class like this:

 class OuterClass {
    Runnable run;

    void method() {
       final int a = 8;
       this.run = new Runnable() {
          public void run() {
             System.out.println(a);
          }
       };
    }
 }

Now suppose I try to serialize this, which contains an object of this inner class type. My compiler names that class OuterClass$1 and gives it a field called val$a. But the exact names to be used in this situation are not part of the compiler's spec. Another compiler might choose to call the inner class OuterClass$method$1. In that case, serializing in one compiled version and deserializing in the other would fail, even though the same source file was used.

(Plus, there's also the problem that an anonymous inner class does not have a no-args constructor. But due to the problem above, even a named inner class cannot reliably serialize)

like image 146
Russell Zahniser Avatar answered Oct 15 '22 11:10

Russell Zahniser


Consider the following code:

public class Main {
    public static void main(String[] args) {
        final int x = Integer.valueOf(args[0]);
        new Object() {
            void print() {
                System.out.println(x);
            }
        }.print();
    }
}

My compiler calls the anonymous inner class Main$1. When I disassemble it, I see that a copy of the value of x from the outer scope is stored in a private field called val$x:

private final int val$x;

This is an example of what the bold part is talking about.

like image 44
NPE Avatar answered Oct 15 '22 10:10

NPE