mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8133977: add specification for serialized forms
Reviewed-by: chegar, plevart, scolebourne
This commit is contained in:
parent
8fe063908e
commit
1dd84f024f
4 changed files with 124 additions and 11 deletions
|
@ -28,6 +28,7 @@ package java.util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InvalidObjectException;
|
import java.io.InvalidObjectException;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.ObjectStreamException;
|
import java.io.ObjectStreamException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@ -607,7 +608,10 @@ class ImmutableCollections {
|
||||||
// ---------- Serialization Proxy ----------
|
// ---------- Serialization Proxy ----------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization proxy class for immutable collections.
|
* A unified serialization proxy class for the immutable collections.
|
||||||
|
*
|
||||||
|
* @serial
|
||||||
|
* @since 9
|
||||||
*/
|
*/
|
||||||
final class CollSer implements Serializable {
|
final class CollSer implements Serializable {
|
||||||
private static final long serialVersionUID = 6309168927139932177L;
|
private static final long serialVersionUID = 6309168927139932177L;
|
||||||
|
@ -616,14 +620,114 @@ final class CollSer implements Serializable {
|
||||||
static final int IMM_SET = 2;
|
static final int IMM_SET = 2;
|
||||||
static final int IMM_MAP = 3;
|
static final int IMM_MAP = 3;
|
||||||
|
|
||||||
private final int flags;
|
/**
|
||||||
private final Object[] array;
|
* Indicates the type of collection that is serialized.
|
||||||
|
* The low order 8 bits have the value 1 for an immutable
|
||||||
|
* {@code List}, 2 for an immutable {@code Set}, and 3 for
|
||||||
|
* an immutable {@code Map}. Any other value causes an
|
||||||
|
* {@link InvalidObjectException} to be thrown. The high
|
||||||
|
* order 24 bits are zero when an instance is serialized,
|
||||||
|
* and they are ignored when an instance is deserialized.
|
||||||
|
* They can thus be used by future implementations without
|
||||||
|
* causing compatibility issues.
|
||||||
|
*
|
||||||
|
* <p>The tag value also determines the interpretation of the
|
||||||
|
* transient {@code Object[] array} field.
|
||||||
|
* For {@code List} and {@code Set}, the array's length is the size
|
||||||
|
* of the collection, and the array contains the elements of the collection.
|
||||||
|
* Null elements are not allowed. For {@code Set}, duplicate elements
|
||||||
|
* are not allowed.
|
||||||
|
*
|
||||||
|
* <p>For {@code Map}, the array's length is twice the number of mappings
|
||||||
|
* present in the map. The array length is necessarily even.
|
||||||
|
* The array contains a succession of key and value pairs:
|
||||||
|
* {@code k1, v1, k2, v2, ..., kN, vN.} Nulls are not allowed,
|
||||||
|
* and duplicate keys are not allowed.
|
||||||
|
*
|
||||||
|
* @serial
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
private final int tag;
|
||||||
|
|
||||||
CollSer(int f, Object... a) {
|
/**
|
||||||
flags = f;
|
* @serial
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
private transient Object[] array;
|
||||||
|
|
||||||
|
CollSer(int t, Object... a) {
|
||||||
|
tag = t;
|
||||||
array = a;
|
array = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads objects from the stream and stores them
|
||||||
|
* in the transient {@code Object[] array} field.
|
||||||
|
*
|
||||||
|
* @serialData
|
||||||
|
* A nonnegative int, indicating the count of objects,
|
||||||
|
* followed by that many objects.
|
||||||
|
*
|
||||||
|
* @param ois the ObjectInputStream from which data is read
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
* @throws ClassNotFoundException if a serialized class cannot be loaded
|
||||||
|
* @throws InvalidObjectException if the count is negative
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||||
|
ois.defaultReadObject();
|
||||||
|
int len = ois.readInt();
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
throw new InvalidObjectException("negative length " + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
Object[] a = new Object[len];
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
a[i] = ois.readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
array = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes objects to the stream from
|
||||||
|
* the transient {@code Object[] array} field.
|
||||||
|
*
|
||||||
|
* @serialData
|
||||||
|
* A nonnegative int, indicating the count of objects,
|
||||||
|
* followed by that many objects.
|
||||||
|
*
|
||||||
|
* @param oos the ObjectOutputStream to which data is written
|
||||||
|
* @throws IOException if an I/O error occurs
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||||
|
oos.defaultWriteObject();
|
||||||
|
oos.writeInt(array.length);
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
oos.writeObject(array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns an immutable collection from this proxy class.
|
||||||
|
* The instance returned is created as if by calling one of the
|
||||||
|
* static factory methods for
|
||||||
|
* <a href="List.html#immutable">List</a>,
|
||||||
|
* <a href="Map.html#immutable">Map</a>, or
|
||||||
|
* <a href="Set.html#immutable">Set</a>.
|
||||||
|
* This proxy class is the serial form for all immutable collection instances,
|
||||||
|
* regardless of implementation type. This is necessary to ensure that the
|
||||||
|
* existence of any particular implementation type is kept out of the
|
||||||
|
* serialized form.
|
||||||
|
*
|
||||||
|
* @return a collection created from this proxy object
|
||||||
|
* @throws InvalidObjectException if the tag value is illegal or if an exception
|
||||||
|
* is thrown during creation of the collection
|
||||||
|
* @throws ObjectStreamException if another serialization error has occurred
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
private Object readResolve() throws ObjectStreamException {
|
private Object readResolve() throws ObjectStreamException {
|
||||||
try {
|
try {
|
||||||
if (array == null) {
|
if (array == null) {
|
||||||
|
@ -631,8 +735,8 @@ final class CollSer implements Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// use low order 8 bits to indicate "kind"
|
// use low order 8 bits to indicate "kind"
|
||||||
// ignore high order bits
|
// ignore high order 24 bits
|
||||||
switch (flags & 0xff) {
|
switch (tag & 0xff) {
|
||||||
case IMM_LIST:
|
case IMM_LIST:
|
||||||
return List.of(array);
|
return List.of(array);
|
||||||
case IMM_SET:
|
case IMM_SET:
|
||||||
|
@ -646,7 +750,7 @@ final class CollSer implements Serializable {
|
||||||
return new ImmutableCollections.MapN<>(array);
|
return new ImmutableCollections.MapN<>(array);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
throw new InvalidObjectException(String.format("invalid flags 0x%x", flags));
|
throw new InvalidObjectException(String.format("invalid flags 0x%x", tag));
|
||||||
}
|
}
|
||||||
} catch (NullPointerException|IllegalArgumentException ex) {
|
} catch (NullPointerException|IllegalArgumentException ex) {
|
||||||
InvalidObjectException ioe = new InvalidObjectException("invalid object");
|
InvalidObjectException ioe = new InvalidObjectException("invalid object");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -107,6 +107,9 @@ import java.util.function.UnaryOperator;
|
||||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||||
|
* <li>They are serialized as specified on the
|
||||||
|
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
|
||||||
|
* page.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>This interface is a member of the
|
* <p>This interface is a member of the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -133,6 +133,9 @@ import java.io.Serializable;
|
||||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||||
|
* <li>They are serialized as specified on the
|
||||||
|
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
|
||||||
|
* page.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>This interface is a member of the
|
* <p>This interface is a member of the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -84,6 +84,9 @@ package java.util;
|
||||||
* Factories are free to create new instances or reuse existing ones. Therefore,
|
* Factories are free to create new instances or reuse existing ones. Therefore,
|
||||||
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
* identity-sensitive operations on these instances (reference equality ({@code ==}),
|
||||||
* identity hash code, and synchronization) are unreliable and should be avoided.
|
* identity hash code, and synchronization) are unreliable and should be avoided.
|
||||||
|
* <li>They are serialized as specified on the
|
||||||
|
* <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
|
||||||
|
* page.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>This interface is a member of the
|
* <p>This interface is a member of the
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue