package com.example; import static java.lang.String.join; import static java.util.Collections.nCopies; import static java.util.Collections.emptyList; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.ArrayList; import java.util.LinkedList; import java.util.Stack; import java.util.Vector; import java.util.Arrays; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.ObjectOutput; import java.io.ObjectInput; import java.io.Serializable; import java.io.Externalizable; import java.nio.ByteBuffer; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Demo { private static void writeDemo(String filename, Object... objects) throws Exception { System.out.println("== Writing " + filename + " =="); try (FileOutputStream fout = new FileOutputStream(filename+".obj", false); ObjectOutputStream oos = new ObjectOutputStream(fout);) { for (Object o : objects) { oos.writeObject(o); } } } private static void resetDemo() throws Exception { try (FileOutputStream fout = new FileOutputStream("reset.obj", false); ObjectOutputStream oos = new ObjectOutputStream(fout);) { oos.writeObject("helloWorld"); // handle #1 oos.writeObject("helloWorld"); // ref to handle #1 oos.reset(); oos.writeObject("foobar"); // handle #1 again oos.writeObject("foobar"); // ref to handle #1 shouldn't be old value } } private static void blockData() throws Exception { try (FileOutputStream fout = new FileOutputStream("block.obj", false); ObjectOutputStream oos = new ObjectOutputStream(fout);) { oos.writeInt(42); oos.writeLong(84); // 42 but twice as long oos.writeUTF("helloWorld"); } } private static void longBlockData() throws Exception { try (FileOutputStream fout = new FileOutputStream("block_long.obj", false); ObjectOutputStream oos = new ObjectOutputStream(fout);) { byte[] bytes = new byte[256]; // anything over 255 is long oos.write(bytes); } } public static void main(String[] args) throws Exception { writeDemo("pojo", new Parent()); writeDemo("extended_pojo", new Child(1, "helloWorld")); writeDemo("childArray", (Object)new Child[]{ new Child(2, "foo"), new Child(3, "bar")}); Map proxy = (Map) Proxy.newProxyInstance( MeaningOfLife.class.getClassLoader(), new Class[] { Map.class }, new MeaningOfLife()); writeDemo("proxy", proxy); // Write String - handled differently to object writeDemo("strings", "helloWorld", "hello", "world", "helloWorld"); String lorem = "Lorem ipsum dolor sit amet," + "consectetur adipiscing elit," + "sed do eiusmod tempor incididunt ut" + "labore et dolore magna aliqua"; writeDemo("string_long", join("\n", nCopies(600, lorem))); // Write ArrayList of children - including previously seen one List children = new ArrayList<>(); Child c = new Child(4, "duplicate"); children.add(new Child(5, "foobar")); children.add(c); children.add(c); writeDemo("arraylist", children); // Write null writeDemo("null", (Object)null); // Write enum type writeDemo("enum", Direction.EAST); // Write primitive arrays double[] arr = new double[] {1.2, 2.3, 3.4, 4.5}; boolean[] truth = new boolean[] {true, true, false, true}; writeDemo("array_primitive", arr, truth); // Write nested primitive array boolean[][] nested = new boolean[][]{{true, false},{false, true}}; writeDemo("array_nested", (Object)nested); // Write primitives as object - casts to Boxed versions writeDemo( "primitives", true, 'A', (short)-42, -23, -84L, 1.23f, 4.56, (byte)76, Float.NaN, Double.NaN, Double.POSITIVE_INFINITY ); // Write a class description without an instance writeDemo("class_only", Parent.class); // Write an object with a reference to itself writeDemo("loop_reference", new Loop()); // write an object with custon writeObject method Custom cust = new Custom(1,2,"helloWorld"); CustomChild custChild = new CustomChild(3, 5, "fooBar"); writeDemo("custom_write", cust, custChild); // Serialize record type writeDemo("sample_record", new SampleRecord(42, "helloWorld")); // Reset and re-reread resetDemo(); // send raw data blockData(); longBlockData(); Extern ext = new Extern(17); writeDemo("extern", ext); List names = Arrays.asList("foo", "foo", "bar", "buzz", "fizz"); Polymorphic arrays = new Polymorphic(names); Polymorphic array = new Polymorphic(new ArrayList(names)); Polymorphic linked = new Polymorphic(new LinkedList(names)); Stack nameStack = new Stack(); names.stream().forEach(nameStack::push); Polymorphic stack = new Polymorphic(nameStack); Polymorphic empty = new Polymorphic(emptyList()); Polymorphic vec = new Polymorphic(new Vector<>(names)); writeDemo("polymorphism", arrays, array, linked, stack, empty, vec); } } class Parent implements Serializable { int i = 13; String foo = "bar"; } class Child extends Parent { int i = 43; Direction d = Direction.EAST; String bar = "HelloWorld"; double[] arr = new double[] {1.2, 2.3, 3.4, 4.5}; Other other = new Other(); Child(int i, String bar) { this.i = i; this.bar = bar; } } class Loop implements Serializable { private Loop loop; public Loop() { this.loop = this; } } class Other implements Serializable { String abc = "def"; } enum Direction { NORTH("N"), EAST("E"), SOUTH("S"), WEST("W"); private String abbr; private int count; Direction(String abbr) { this.abbr = abbr; this.count = 0; } public void inc() { count += 1; } } class Custom implements Serializable { int i; transient int j; transient String msg; public Custom(int i, int j, String msg) { this.i = i; this.j = j; this.msg = msg; } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); oos.writeInt(j); oos.writeObject(msg); oos.writeInt(j); } } class CustomChild extends Custom { int i = 23; transient int foo = 211; public CustomChild(int i, int j, String msg) { super(i,j,msg); this.i = i*j; } private void writeObject(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); oos.writeInt(foo); } } class MeaningOfLife implements InvocationHandler, Serializable { private Integer foo; public Object invoke(Object proxy, Method method, Object[] args) { // System.out.println("Proxy returned: " + 42); return 42; } } class Extern extends Parent implements Externalizable { private static final long serialVersionUID = 1234L; private int ext; public Extern(int i) { this.ext = i; } public void writeExternal(ObjectOutput out) throws IOException { System.out.println("writing extern"); out.writeInt(ext); } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { byte[] bits = new byte[4]; in.read(bits); this.ext = ByteBuffer.wrap(bits).getInt(); } } class Polymorphic implements Serializable { private List names; public Polymorphic(List names) { this.names = names; } } record SampleRecord(int i, String s) implements Serializable {}