views:

315

answers:

4

This morning my boss and I had a long and ultimately fruitless discussion about this, in the context of trying to diagnose performance problems with a web application. We didn't really come to any conclusions.

I think we're right in thinking that Serializable non-static inner classes have issues, but we're not sure precisely what the issues are or what exactly to avoid (we reasoned that we couldn't always simply avoid it). Can anyone suggest any guidelines for not getting in trouble with this issue?

+4  A: 

An inner class holds a reference to its outer class, so attempting to serialize the inner will also serialize the outer -- as well as any other objects that the outer might hold. This could result in a huge object graph. Or it could fail, if the outer has state that can't be serialized (such as an InputStream object).

That said, there are times when you have to make inner classes Serializable, even if you never plan to serialize them. For example, if you're working with Swing.

If you do plan to serialize these objects, I'd question why they'd need to be inner classes irrespective of performance. Generally, you're only going to serialize data containers, and such containers rarely (if ever) need a reference to some "parent" class. Consider making these objects nested (static) classes rather than inner classes.

kdgregory
+2  A: 

Just being aware that a serialized inner class has an implicit reference to its containing object will go a long way. That reference does have a number of implications:

  • The reference is automatically generated, so it can't be transient
  • The outer class must be serializable
  • The outer class will be automatically serialized with the inner class
  • The outer object can't be disassociated from its inner object

Probably the main guideline I can dredge up is "don't serialize inner classes except from their containing object." I can't think of any more gotchas.

John Calsbeek
A: 

A thought. If your outer class includes a (non-transient) collection of instances of the inner class, then each time you serialise one of the inner class instances, you will actually pull all of them into the serialization.

Stephen C
The Java serialization mechanism is smart enough to know when an object has already been written to a stream, and subsequent references to that object use an ID. This allows you to rebuild an object graph and retain identity within the graph.
kdgregory
A: 

You can make the class Externalizable and write your own custom writeExternal and readExternal methods which only send the fields you want.

http://java.sun.com/javase/6/docs/api/java/io/Externalizable.html

Peter Lawrey