EN
Java FIX for java.io.Not Serializable Exception: java.util.Optional
13 points
How to solve java util Optional serializable exception?
Full stack trace:
xxxxxxxxxx
1
Exception in thread "main" java.io.NotSerializableException: java.util.Optional
2
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
3
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
4
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
5
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
6
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
7
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
Here is my code which explains what I've tried so far
Below code tries to serialize field Optional age
As the result we get:
xxxxxxxxxx
1
Exception in thread "main" java.io.NotSerializableException: java.util.Optional
My code to get this exception:
xxxxxxxxxx
1
import java.io.ByteArrayOutputStream;
2
import java.io.ObjectOutputStream;
3
import java.io.Serializable;
4
import java.util.Optional;
5
6
public class JavaUtilOptionalNotSerializableException {
7
8
private static class Foo implements Serializable {
9
private static final long serialVersionUID = 1L;
10
11
private final String name;
12
private final Optional<Integer> age;
13
14
private Foo(String name, Integer age) {
15
this.name = name;
16
this.age = Optional.ofNullable(age);
17
}
18
19
public String getName() {
20
return name;
21
}
22
23
public Optional<Integer> getAge() {
24
return age;
25
}
26
}
27
28
public static void main(String[] args) throws Exception {
29
/*
30
Exception in thread "main" java.io.NotSerializableException:
31
java.util.Optional
32
*/
33
tryToSerialize();
34
}
35
36
private static void tryToSerialize() throws Exception {
37
Foo foo = new Foo("123", 456);
38
byte[] arr;
39
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
40
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
41
oos.writeObject(foo);
42
arr = baos.toByteArray();
43
}
44
assert arr != null;
45
}
46
}
Solution no 1 to this problem is just do not use optional as field value
Instead use it as return type from the getter method
eg:
xxxxxxxxxx
1
private final Integer age; // diff1: without Optional
2
3
public Optional<Integer> getAge() {
4
// diff2: each method invocation return new Optional
5
return Optional.ofNullable(age);
6
}
Entire code which solves your problem:
xxxxxxxxxx
1
import java.io.ByteArrayOutputStream;
2
import java.io.ObjectOutputStream;
3
import java.io.Serializable;
4
import java.util.Optional;
5
6
public class JavaUtilOptionalSolution {
7
8
private static class Foo implements Serializable {
9
private static final long serialVersionUID = 1L;
10
11
private final String name;
12
private final Integer age; // diff1: without Optional
13
14
private Foo(String name, Integer age) {
15
this.name = name;
16
this.age = age;
17
}
18
19
public String getName() {
20
return name;
21
}
22
23
public Optional<Integer> getAge() {
24
// diff2: each method invocation return new Optional
25
return Optional.ofNullable(age);
26
}
27
}
28
29
public static void main(String[] args) throws Exception {
30
// serialization works
31
tryToSerialize();
32
}
33
34
private static void tryToSerialize() throws Exception {
35
Foo foo = new Foo("123", 456);
36
byte[] arr;
37
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
38
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
39
oos.writeObject(foo);
40
arr = baos.toByteArray();
41
}
42
assert arr != null;
43
}
44
}
Guava internally
xxxxxxxxxx
1
// com.google.common.base.Optional
2
3
public abstract class Optional implements Serializable {
4
// ..
5
}