8192935: Fix EnumSet's SerializationProxy javadoc

Reviewed-by: smarks, rriggs
This commit is contained in:
Martin Buchholz 2017-12-03 13:06:51 -08:00
parent a820e5eaa8
commit ed69a7db9c
2 changed files with 30 additions and 12 deletions
src/java.base/share/classes/java/util
test/jdk/java/util/EnumSet

@ -75,7 +75,6 @@ import jdk.internal.misc.SharedSecrets;
* @author Josh Bloch
* @since 1.5
* @see EnumMap
* @serial exclude
*/
@SuppressWarnings("serial") // No serialVersionUID due to usage of
// serial proxy pattern
@ -85,12 +84,12 @@ public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
/**
* The class of all the elements of this set.
*/
final Class<E> elementType;
final transient Class<E> elementType;
/**
* All of the values comprising T. (Cached for performance.)
* All of the values comprising E. (Cached for performance.)
*/
final Enum<?>[] universe;
final transient Enum<?>[] universe;
EnumSet(Class<E>elementType, Enum<?>[] universe) {
this.elementType = elementType;
@ -416,7 +415,7 @@ public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
*
* @serial include
*/
private static class SerializationProxy <E extends Enum<E>>
private static class SerializationProxy<E extends Enum<E>>
implements java.io.Serializable
{
@ -441,10 +440,18 @@ public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
elements = set.toArray(ZERO_LENGTH_ENUM_ARRAY);
}
// instead of cast to E, we should perhaps use elementType.cast()
// to avoid injection of forged stream, but it will slow the implementation
/**
* Returns an {@code EnumSet} object with initial state
* held by this proxy.
*
* @return a {@code EnumSet} object with initial state
* held by this proxy
*/
@SuppressWarnings("unchecked")
private Object readResolve() {
// instead of cast to E, we should perhaps use elementType.cast()
// to avoid injection of forged stream, but it will slow the
// implementation
EnumSet<E> result = EnumSet.noneOf(elementType);
for (Enum<?> e : elements)
result.add((E)e);
@ -454,13 +461,24 @@ public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
private static final long serialVersionUID = 362491234563181265L;
}
/**
* Returns a
* <a href="../../serialized-form.html#java.util.EnumSet.SerializationProxy">
* SerializationProxy</a>
* representing the state of this instance.
*
* @return a {@link SerializationProxy}
* representing the state of this instance
*/
Object writeReplace() {
return new SerializationProxy<>(this);
}
// readObject method for the serialization proxy pattern
// See Effective Java, Second Ed., Item 78.
private void readObject(java.io.ObjectInputStream stream)
/**
* @param s the stream
* @throws java.io.InvalidObjectException always
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.InvalidObjectException {
throw new java.io.InvalidObjectException("Proxy required");
}

@ -34,7 +34,7 @@ public class BogusEnumSet {
public static void main(String[] args) throws Throwable {
// This test depends on the current serialVersionUID of EnumSet,
// which may change if the EnumSet class is modified.
// The current value is 4168005130090799668L = 0x39D7BA9531116234L
// The current value is -2409567991088730183L = 0xde8f7eadb5012fb9L
// If the value changes, it will have to be patched into the
// serialized byte stream below at the location noted.
byte[] serializedForm = {
@ -47,7 +47,7 @@ public class BogusEnumSet {
0x11, 0x6a, 0x61, 0x76, 0x61, 0x2e, 0x75, 0x74, 0x69,
0x6c, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x65, 0x74,
// EnumSet's serialVersionUID is the following eight bytes (big-endian)
0x39, (byte)0xd7, (byte)0xba, (byte)0x95, 0x31, 0x11, 0x62, 0x34,
(byte)0xde, (byte)0x8f, 0x7e, (byte)0xad, (byte)0xb5, (byte)0x01, 0x2f, (byte)0xb9,
0x2, 0x0, 0x2, 0x4c, 0x0, 0xb, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
0x54, 0x79, 0x70, 0x65, 0x74, 0x0, 0x11, 0x4c, 0x6a, 0x61, 0x76,
0x61, 0x2f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x43, 0x6c, 0x61, 0x73,