Sending the same but modifed object over ObjectOutputStream
The stream has a reference graph, so an object which is sent twice will not give two objects on the other end, you will only get one. And sending the same object twice separately will give you the same instance twice (each with the same data - which is what you're seeing).
See the reset() method if you want to reset the graph.
Sending the same objects with different fields over an object serialized stream
This is the expected behavior of the ObjectOutputStream
. To quote from the Javadocs:
Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.
Since you are using the same inner class reference, it just sends over a reference to the previously sent object. It does not check all of the fields of all of the objects to see if any of them have changed. I suspect that not only was inner.getValue()
equal to the first object sent but that the inner
object received by the server in the 2nd object was the same object (==
) as the inner
from the first object.
If you had called:
out.reset();
before the sending of the object with the adjusted inner
field, your code should work. The reset()
method clears the reference cache which helps the serialization stream be efficient. As a side note, reset()
is especially necessary if you are sending a large number of temporary objects across a stream because otherwise these objects are cached in memory and can cause heap exhaustion.
ObjectOutputStream writes same instances differently depending on how i open stream
Java serialization, implemented by Object{Output,Input}Stream
, in addition to metadata and data for each object, has a stream header that only occurs once and not for each object. Normally in a file this amounts to a file header. If you want to put multiple streams in one file, you must manage the stream boundaries yourself:
//nopackage
import java.io.*;
public class SO71319428MultipleSerial {
public static void main (String[] args) throws Exception {
User[] a = { new User("Alice",1), new User("Bob",2), new User("Carol",3) };
for( User u : a )
try( ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(filename,true)) ){
oo.writeObject(u);
}
System.out.println("reading "+new File(filename).length());
try( InputStream fi = new FileInputStream(filename) ){
for( int i = 0; i < 3; i++ ){
ObjectInputStream oi = new ObjectInputStream(fi);
System.out.println( oi.readObject() );
// DON'T close because that closes the underlying FileInputStream; just leak instead
}
}
}
public static String filename = "SO71319428.out";
static class User implements Serializable {
String name; int id;
public User(String name, int id){ this.name=name; this.id=id; }
public String toString(){ return name+" is #"+id; }
}
}
->
reading 283
Alice is #1
Bob is #2
Carol is #3
This is less flexible than the single-stream (with multiple objects) approach, because that allows you to write any sequence of objects whose types and end can be recognized when reading without any help; with the multiple-stream approach your code must be able to determine when a stream ends and needs to be restarted.
Having to recreate ObjectOutputStream every time
When you send data on an object stream, it will send each object only once. This means if you modify and object and send it multiple times, you need to either use writeUnshared(mutableObject)
or reset()
which clears the cache of objects already sent.
You can't create an ObjectOutput/InputStream repeatly. If you want to make sure data is sent instead of buffered use flush()
. If you are sending data like int
instead of Objects, try DataOutput/InputStream.
Related Topics
What Is "Compiler Compliance Level" in Eclipse
Cannot Find Firefox Binary in Path. Make Sure Firefox Is Installed
Java Reflection: How to Get the All Getter Methods of a Java Class and Invoke Them
Java.Util.Concurrentmodificationexception Not Thrown When Expected
How Does the Java Cast Operator Work
Java Thread Priority Has No Effect
How to Determine If a List Is Sorted in Java
Java Ternary Without Assignment
What Is Better: Multiple "If" Statements or One "If" with Multiple Conditions
Adding Chartpanel to Jtabbedpane Using JPAnel
How to Access Private Methods and Private Data Members via Reflection
Javafx Launch Another Application
When Does the JPA Set a @Generatedvalue @Id