Skip to content

Commit 0668611

Browse files
committed
Add enum serialization test and Serialization Proxy
1 parent 493f192 commit 0668611

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package scala.runtime;
2+
3+
import java.io.Serializable;
4+
import java.security.AccessController;
5+
import java.security.PrivilegedActionException;
6+
import java.security.PrivilegedExceptionAction;
7+
8+
/** A serialization proxy for singleton enum values */
9+
public final class EnumValueSerializationProxy implements Serializable {
10+
private static final long serialVersionUID = 1L;
11+
private final Class<?> enumClass;
12+
private final int ordinal;
13+
private static final ClassValue<Object[]> enumValues = new ClassValue<Object[]>() {
14+
@Override
15+
protected Object[] computeValue(Class<?> type) {
16+
try {
17+
return AccessController.doPrivileged((PrivilegedExceptionAction<Object[]>) () ->
18+
(Object[])type.getMethod("values").invoke(null));
19+
} catch (PrivilegedActionException e) {
20+
return rethrowRuntime(e.getCause());
21+
}
22+
}
23+
};
24+
25+
private static <T> T rethrowRuntime(Throwable e) {
26+
Throwable cause = e.getCause();
27+
if (cause instanceof RuntimeException) throw (RuntimeException) cause;
28+
else throw new RuntimeException(cause);
29+
}
30+
31+
public EnumValueSerializationProxy(Class<?> enumClass, int ordinal) {
32+
this.enumClass = enumClass;
33+
this.ordinal = ordinal;
34+
}
35+
36+
@SuppressWarnings("unused")
37+
private Object readResolve() {
38+
return enumValues.get(enumClass)[ordinal];
39+
}
40+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import java.io._
2+
import scala.util.Using
3+
4+
enum JColor extends java.lang.Enum[JColor]:
5+
case Red
6+
7+
enum SColor:
8+
case Green
9+
10+
enum SColorTagged[T]:
11+
case Blue extends SColorTagged[Unit]
12+
13+
@main def Test = Using.Manager({ use =>
14+
val buf = use(ByteArrayOutputStream())
15+
val out = use(ObjectOutputStream(buf))
16+
Seq(JColor.Red, SColor.Green, SColorTagged.Blue).foreach(out.writeObject)
17+
val read = use(ByteArrayInputStream(buf.toByteArray))
18+
val in = use(ObjectInputStream(read))
19+
val Seq(Red @ _, Green @ _, Blue @ _) = (1 to 3).map(_ => in.readObject)
20+
assert(Red eq JColor.Red, JColor.Red)
21+
assert(Green eq SColor.Green, SColor.Green)
22+
assert(Blue eq SColorTagged.Blue, SColorTagged.Blue)
23+
}).get

0 commit comments

Comments
 (0)