Reputation: 1813
Let's say that I create an instance of class B, which has an static variable x, assigned with a value of 3 in the class B declaration. In the main() method, I do this:
B b = new B();
b.x = 7; //allowed to use an instance to set the static member value
After this, b is serialized and then de-serialized. Then, the following line occurs:
System.out.println ("static: " + b.x);
What's the value? 7 or 3?
I know static variables are not serialized, however, since there is only one copy of the static member for the whole class, and the value is set to 7, should it be preserved after de-serializing an instance?
Upvotes: 1
Views: 5512
Reputation: 14479
Use the following code to serialize and deserialize and object to / from an in-memory stream:
package com.example.serialization;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import junit.framework.TestCase;
public class SerializationTest extends TestCase {
public void testStaticValueAfterSerialization() {
B b = new B();
b.x = 7; //allowed to use an instance to set the static member value
B deserializedB = copyObject(b);
assertEquals("b.x should be 7 after serialization", 7, deserializedB.x);
}
private <T extends Serializable> T copyObject(final T source) {
if (source == null)
throw new IllegalArgumentException("source is null");
final T copy;
try {
copy = serializationClone(source);
} catch (Exception e) {
// (optional) die gloriously!
throw new AssertionError("Error copying: " + source, e);
}
return copy;
}
private <T extends Serializable> T serializationClone(final T source)
throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteStream);
// 1. serialize the object to the in-memory output stream
outputStream.writeObject(source);
ObjectInputStream inputStream = new ObjectInputStream(
new ByteArrayInputStream(byteStream.toByteArray()));
// 2. deserialize the object from the in-memory input stream
@SuppressWarnings("unchecked")
final T copy = (T) inputStream.readObject();
return copy; // NOPMD : v. supra
}
}
After creating that class, run it with a JUnit runner and see if the test passes! If you like, you can write the result to a file in one test case. Then in another test case, read the result from a file!
Upvotes: 1
Reputation: 26149
If you deserialize it in the same instance of the JVM, your second snippet will return 7. This is because the value of b.x is set to 7. That hasn't changed because an instance of B was serialized and deserialized.
If you serialize the object, shutdown the JVM, bring up a new JVM, and then deserialize the object (without setting b.x anywhere other than the static initialization), the value of b.x will be 3.
Upvotes: 7
Reputation: 328604
Since static initializers run exactly once, the value is 7
.
Upvotes: 0
Reputation: 69342
Here's what happens:
If you want the logic you describe, you need to add another static variable which counts the number of instances created and override the writeObject
and readObject
methods with your custom logic.
Upvotes: 8