Method from java.io.ObjectStreamClass Detail: |
void checkDefaultSerialize() throws InvalidClassException {
if (defaultSerializeEx != null) {
InvalidClassException ice =
new InvalidClassException(defaultSerializeEx.classname,
defaultSerializeEx.getMessage());
ice.initCause(defaultSerializeEx);
throw ice;
}
}
Throws an InvalidClassException if objects whose class is represented by
this descriptor should not be permitted to use default serialization
(e.g., if the class declares serializable fields that do not correspond
to actual fields, and hence must use the GetField API). This method
does not apply to deserialization of enum constants. |
void checkDeserialize() throws InvalidClassException {
if (deserializeEx != null) {
InvalidClassException ice =
new InvalidClassException(deserializeEx.classname,
deserializeEx.getMessage());
ice.initCause(deserializeEx);
throw ice;
}
}
Throws an InvalidClassException if object instances referencing this
class descriptor should not be allowed to deserialize. This method does
not apply to deserialization of enum constants. |
void checkSerialize() throws InvalidClassException {
if (serializeEx != null) {
InvalidClassException ice =
new InvalidClassException(serializeEx.classname,
serializeEx.getMessage());
ice.initCause(serializeEx);
throw ice;
}
}
Throws an InvalidClassException if objects whose class is represented by
this descriptor should not be allowed to serialize. This method does
not apply to serialization of enum constants. |
public Class<?> forClass() {
return cl;
}
Return the class in the local VM that this version is mapped to. Null
is returned if there is no corresponding local class. |
ClassDataSlot[] getClassDataLayout() throws InvalidClassException {
// REMIND: synchronize instead of relying on volatile?
if (dataLayout == null) {
dataLayout = getClassDataLayout0();
}
return dataLayout;
}
Returns array of ClassDataSlot instances representing the data layout
(including superclass data) for serialized objects described by this
class descriptor. ClassDataSlots are ordered by inheritance with those
containing "higher" superclasses appearing first. The final
ClassDataSlot contains a reference to this descriptor. |
public ObjectStreamField getField(String name) {
return getField(name, null);
}
Get the field of this class by name. |
ObjectStreamField getField(String name,
Class<?> type) {
for (int i = 0; i < fields.length; i++) {
ObjectStreamField f = fields[i];
if (f.getName().equals(name)) {
if (type == null ||
(type == Object.class && !f.isPrimitive()))
{
return f;
}
Class< ? > ftype = f.getType();
if (ftype != null && type.isAssignableFrom(ftype)) {
return f;
}
}
}
return null;
}
Looks up a serializable field of the represented class by name and type.
A specified type of null matches all types, Object.class matches all
non-primitive types, and any other non-null type matches assignable
types only. Returns matching field, or null if no match found. |
public ObjectStreamField[] getFields() {
return getFields(true);
}
Return an array of the fields of this serializable class. |
ObjectStreamField[] getFields(boolean copy) {
return copy ? fields.clone() : fields;
}
Returns arrays of ObjectStreamFields representing the serializable
fields of the represented class. If copy is true, a clone of this class
descriptor's field array is returned, otherwise the array itself is
returned. |
ObjectStreamClass getLocalDesc() {
return localDesc;
}
Returns the "local" class descriptor for the class associated with this
class descriptor (i.e., the result of
ObjectStreamClass.lookup(this.forClass())) or null if there is no class
associated with this descriptor. |
public String getName() {
return name;
}
Returns the name of the class described by this descriptor.
This method returns the name of the class in the format that
is used by the Class#getName method. |
int getNumObjFields() {
return numObjFields;
}
Returns number of non-primitive serializable fields of represented
class. |
void getObjFieldValues(Object obj,
Object[] vals) {
fieldRefl.getObjFieldValues(obj, vals);
}
Fetches the serializable object field values of object obj and stores
them in array vals starting at offset 0. It is the responsibility of
the caller to ensure that obj is of the proper type if non-null. |
int getPrimDataSize() {
return primDataSize;
}
Returns aggregate size (in bytes) of marshalled primitive field values
for represented class. |
void getPrimFieldValues(Object obj,
byte[] buf) {
fieldRefl.getPrimFieldValues(obj, buf);
}
Fetches the serializable primitive field values of object obj and
marshals them into byte array buf starting at offset 0. It is the
responsibility of the caller to ensure that obj is of the proper type if
non-null. |
ClassNotFoundException getResolveException() {
return resolveEx;
}
Returns ClassNotFoundException (if any) thrown while attempting to
resolve local class corresponding to this class descriptor. |
public long getSerialVersionUID() {
// REMIND: synchronize instead of relying on volatile?
if (suid == null) {
suid = AccessController.doPrivileged(
new PrivilegedAction< Long >() {
public Long run() {
return computeDefaultSUID(cl);
}
}
);
}
return suid.longValue();
}
Return the serialVersionUID for this class. The serialVersionUID
defines a set of classes all with the same name that have evolved from a
common root class and agree to be serialized and deserialized using a
common format. NonSerializable classes have a serialVersionUID of 0L. |
ObjectStreamClass getSuperDesc() {
return superDesc;
}
Returns superclass descriptor. Note that on the receiving side, the
superclass descriptor may be bound to a class that is not a superclass
of the subclass descriptor's bound class. |
boolean hasBlockExternalData() {
return hasBlockExternalData;
}
Returns true if class descriptor represents externalizable class that
has written its data in 1.2 (block data) format, false otherwise. |
boolean hasReadObjectMethod() {
return (readObjectMethod != null);
}
Returns true if represented class is serializable (but not
externalizable) and defines a conformant readObject method. Otherwise,
returns false. |
boolean hasReadObjectNoDataMethod() {
return (readObjectNoDataMethod != null);
}
Returns true if represented class is serializable (but not
externalizable) and defines a conformant readObjectNoData method.
Otherwise, returns false. |
boolean hasReadResolveMethod() {
return (readResolveMethod != null);
}
Returns true if represented class is serializable or externalizable and
defines a conformant readResolve method. Otherwise, returns false. |
boolean hasWriteObjectData() {
return hasWriteObjectData;
}
Returns true if class descriptor represents serializable (but not
externalizable) class which has written its data via a custom
writeObject() method, false otherwise. |
boolean hasWriteObjectMethod() {
return (writeObjectMethod != null);
}
Returns true if represented class is serializable (but not
externalizable) and defines a conformant writeObject method. Otherwise,
returns false. |
boolean hasWriteReplaceMethod() {
return (writeReplaceMethod != null);
}
Returns true if represented class is serializable or externalizable and
defines a conformant writeReplace method. Otherwise, returns false. |
void initNonProxy(ObjectStreamClass model,
Class<?> cl,
ClassNotFoundException resolveEx,
ObjectStreamClass superDesc) throws InvalidClassException {
this.cl = cl;
this.resolveEx = resolveEx;
this.superDesc = superDesc;
name = model.name;
suid = Long.valueOf(model.getSerialVersionUID());
isProxy = false;
isEnum = model.isEnum;
serializable = model.serializable;
externalizable = model.externalizable;
hasBlockExternalData = model.hasBlockExternalData;
hasWriteObjectData = model.hasWriteObjectData;
fields = model.fields;
primDataSize = model.primDataSize;
numObjFields = model.numObjFields;
if (cl != null) {
localDesc = lookup(cl, true);
if (localDesc.isProxy) {
throw new InvalidClassException(
"cannot bind non-proxy descriptor to a proxy class");
}
if (isEnum != localDesc.isEnum) {
throw new InvalidClassException(isEnum ?
"cannot bind enum descriptor to a non-enum class" :
"cannot bind non-enum descriptor to an enum class");
}
if (serializable == localDesc.serializable &&
!cl.isArray() &&
suid.longValue() != localDesc.getSerialVersionUID())
{
throw new InvalidClassException(localDesc.name,
"local class incompatible: " +
"stream classdesc serialVersionUID = " + suid +
", local class serialVersionUID = " +
localDesc.getSerialVersionUID());
}
if (!classNamesEqual(name, localDesc.name)) {
throw new InvalidClassException(localDesc.name,
"local class name incompatible with stream class " +
"name \"" + name + "\"");
}
if (!isEnum) {
if ((serializable == localDesc.serializable) &&
(externalizable != localDesc.externalizable))
{
throw new InvalidClassException(localDesc.name,
"Serializable incompatible with Externalizable");
}
if ((serializable != localDesc.serializable) ||
(externalizable != localDesc.externalizable) ||
!(serializable || externalizable))
{
deserializeEx = new InvalidClassException(localDesc.name,
"class invalid for deserialization");
}
}
cons = localDesc.cons;
writeObjectMethod = localDesc.writeObjectMethod;
readObjectMethod = localDesc.readObjectMethod;
readObjectNoDataMethod = localDesc.readObjectNoDataMethod;
writeReplaceMethod = localDesc.writeReplaceMethod;
readResolveMethod = localDesc.readResolveMethod;
if (deserializeEx == null) {
deserializeEx = localDesc.deserializeEx;
}
}
fieldRefl = getReflector(fields, localDesc);
// reassign to matched fields so as to reflect local unshared settings
fields = fieldRefl.getFields();
}
Initializes class descriptor representing a non-proxy class. |
void initProxy(Class<?> cl,
ClassNotFoundException resolveEx,
ObjectStreamClass superDesc) throws InvalidClassException {
this.cl = cl;
this.resolveEx = resolveEx;
this.superDesc = superDesc;
isProxy = true;
serializable = true;
suid = Long.valueOf(0);
fields = NO_FIELDS;
if (cl != null) {
localDesc = lookup(cl, true);
if (!localDesc.isProxy) {
throw new InvalidClassException(
"cannot bind proxy descriptor to a non-proxy class");
}
name = localDesc.name;
externalizable = localDesc.externalizable;
cons = localDesc.cons;
writeReplaceMethod = localDesc.writeReplaceMethod;
readResolveMethod = localDesc.readResolveMethod;
deserializeEx = localDesc.deserializeEx;
}
fieldRefl = getReflector(fields, localDesc);
}
Initializes class descriptor representing a proxy class. |
void invokeReadObject(Object obj,
ObjectInputStream in) throws ClassNotFoundException, IOException, UnsupportedOperationException {
if (readObjectMethod != null) {
try {
readObjectMethod.invoke(obj, new Object[]{ in });
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof ClassNotFoundException) {
throw (ClassNotFoundException) th;
} else if (th instanceof IOException) {
throw (IOException) th;
} else {
throwMiscException(th);
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError();
}
} else {
throw new UnsupportedOperationException();
}
}
Invokes the readObject method of the represented serializable class.
Throws UnsupportedOperationException if this class descriptor is not
associated with a class, or if the class is externalizable,
non-serializable or does not define readObject. |
void invokeReadObjectNoData(Object obj) throws IOException, UnsupportedOperationException {
if (readObjectNoDataMethod != null) {
try {
readObjectNoDataMethod.invoke(obj, (Object[]) null);
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof ObjectStreamException) {
throw (ObjectStreamException) th;
} else {
throwMiscException(th);
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError();
}
} else {
throw new UnsupportedOperationException();
}
}
Invokes the readObjectNoData method of the represented serializable
class. Throws UnsupportedOperationException if this class descriptor is
not associated with a class, or if the class is externalizable,
non-serializable or does not define readObjectNoData. |
Object invokeReadResolve(Object obj) throws IOException, UnsupportedOperationException {
if (readResolveMethod != null) {
try {
return readResolveMethod.invoke(obj, (Object[]) null);
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof ObjectStreamException) {
throw (ObjectStreamException) th;
} else {
throwMiscException(th);
throw new InternalError(); // never reached
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError();
}
} else {
throw new UnsupportedOperationException();
}
}
Invokes the readResolve method of the represented serializable class and
returns the result. Throws UnsupportedOperationException if this class
descriptor is not associated with a class, or if the class is
non-serializable or does not define readResolve. |
void invokeWriteObject(Object obj,
ObjectOutputStream out) throws IOException, UnsupportedOperationException {
if (writeObjectMethod != null) {
try {
writeObjectMethod.invoke(obj, new Object[]{ out });
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof IOException) {
throw (IOException) th;
} else {
throwMiscException(th);
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError();
}
} else {
throw new UnsupportedOperationException();
}
}
Invokes the writeObject method of the represented serializable class.
Throws UnsupportedOperationException if this class descriptor is not
associated with a class, or if the class is externalizable,
non-serializable or does not define writeObject. |
Object invokeWriteReplace(Object obj) throws IOException, UnsupportedOperationException {
if (writeReplaceMethod != null) {
try {
return writeReplaceMethod.invoke(obj, (Object[]) null);
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof ObjectStreamException) {
throw (ObjectStreamException) th;
} else {
throwMiscException(th);
throw new InternalError(); // never reached
}
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError();
}
} else {
throw new UnsupportedOperationException();
}
}
Invokes the writeReplace method of the represented serializable class and
returns the result. Throws UnsupportedOperationException if this class
descriptor is not associated with a class, or if the class is
non-serializable or does not define writeReplace. |
boolean isEnum() {
return isEnum;
}
Returns true if class descriptor represents an enum type, false
otherwise. |
boolean isExternalizable() {
return externalizable;
}
Returns true if represented class implements Externalizable, false
otherwise. |
boolean isInstantiable() {
return (cons != null);
}
Returns true if represented class is serializable/externalizable and can
be instantiated by the serialization runtime--i.e., if it is
externalizable and defines a public no-arg constructor, or if it is
non-externalizable and its first non-serializable superclass defines an
accessible no-arg constructor. Otherwise, returns false. |
boolean isProxy() {
return isProxy;
}
Returns true if class descriptor represents a dynamic proxy class, false
otherwise. |
boolean isSerializable() {
return serializable;
}
Returns true if represented class implements Serializable, false
otherwise. |
public static ObjectStreamClass lookup(Class<?> cl) {
return lookup(cl, false);
}
Find the descriptor for a class that can be serialized. Creates an
ObjectStreamClass instance if one does not exist yet for class. Null is
returned if the specified class does not implement java.io.Serializable
or java.io.Externalizable. |
static ObjectStreamClass lookup(Class<?> cl,
boolean all) {
if (!(all || Serializable.class.isAssignableFrom(cl))) {
return null;
}
processQueue(Caches.localDescsQueue, Caches.localDescs);
WeakClassKey key = new WeakClassKey(cl, Caches.localDescsQueue);
Reference< ? > ref = Caches.localDescs.get(key);
Object entry = null;
if (ref != null) {
entry = ref.get();
}
EntryFuture future = null;
if (entry == null) {
EntryFuture newEntry = new EntryFuture();
Reference< ? > newRef = new SoftReference< >(newEntry);
do {
if (ref != null) {
Caches.localDescs.remove(key, ref);
}
ref = Caches.localDescs.putIfAbsent(key, newRef);
if (ref != null) {
entry = ref.get();
}
} while (ref != null && entry == null);
if (entry == null) {
future = newEntry;
}
}
if (entry instanceof ObjectStreamClass) { // check common case first
return (ObjectStreamClass) entry;
}
if (entry instanceof EntryFuture) {
future = (EntryFuture) entry;
if (future.getOwner() == Thread.currentThread()) {
/*
* Handle nested call situation described by 4803747: waiting
* for future value to be set by a lookup() call further up the
* stack will result in deadlock, so calculate and set the
* future value here instead.
*/
entry = null;
} else {
entry = future.get();
}
}
if (entry == null) {
try {
entry = new ObjectStreamClass(cl);
} catch (Throwable th) {
entry = th;
}
if (future.set(entry)) {
Caches.localDescs.put(key, new SoftReference< Object >(entry));
} else {
// nested lookup call already set future
entry = future.get();
}
}
if (entry instanceof ObjectStreamClass) {
return (ObjectStreamClass) entry;
} else if (entry instanceof RuntimeException) {
throw (RuntimeException) entry;
} else if (entry instanceof Error) {
throw (Error) entry;
} else {
throw new InternalError("unexpected entry: " + entry);
}
}
Looks up and returns class descriptor for given class, or null if class
is non-serializable and "all" is set to false. |
public static ObjectStreamClass lookupAny(Class<?> cl) {
return lookup(cl, true);
}
Returns the descriptor for any class, regardless of whether it
implements Serializable . |
Object newInstance() throws InstantiationException, InvocationTargetException, UnsupportedOperationException {
if (cons != null) {
try {
return cons.newInstance();
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
throw new InternalError();
}
} else {
throw new UnsupportedOperationException();
}
}
Creates a new instance of the represented class. If the class is
externalizable, invokes its public no-arg constructor; otherwise, if the
class is serializable, invokes the no-arg constructor of the first
non-serializable superclass. Throws UnsupportedOperationException if
this class descriptor is not associated with a class, if the associated
class is non-serializable or if the appropriate no-arg constructor is
inaccessible/unavailable. |
static void processQueue(ReferenceQueue<?> queue,
ConcurrentMap<WeakReference, ?> map) {
Reference< ? extends Class< ? > > ref;
while((ref = queue.poll()) != null) {
map.remove(ref);
}
}
Removes from the specified map any keys that have been enqueued
on the specified reference queue. |
void readNonProxy(ObjectInputStream in) throws IOException, ClassNotFoundException {
name = in.readUTF();
suid = Long.valueOf(in.readLong());
isProxy = false;
byte flags = in.readByte();
hasWriteObjectData =
((flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0);
hasBlockExternalData =
((flags & ObjectStreamConstants.SC_BLOCK_DATA) != 0);
externalizable =
((flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0);
boolean sflag =
((flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0);
if (externalizable && sflag) {
throw new InvalidClassException(
name, "serializable and externalizable flags conflict");
}
serializable = externalizable || sflag;
isEnum = ((flags & ObjectStreamConstants.SC_ENUM) != 0);
if (isEnum && suid.longValue() != 0L) {
throw new InvalidClassException(name,
"enum descriptor has non-zero serialVersionUID: " + suid);
}
int numFields = in.readShort();
if (isEnum && numFields != 0) {
throw new InvalidClassException(name,
"enum descriptor has non-zero field count: " + numFields);
}
fields = (numFields > 0) ?
new ObjectStreamField[numFields] : NO_FIELDS;
for (int i = 0; i < numFields; i++) {
char tcode = (char) in.readByte();
String fname = in.readUTF();
String signature = ((tcode == 'L') || (tcode == '[')) ?
in.readTypeString() : new String(new char[] { tcode });
try {
fields[i] = new ObjectStreamField(fname, signature, false);
} catch (RuntimeException e) {
throw (IOException) new InvalidClassException(name,
"invalid descriptor for field " + fname).initCause(e);
}
}
computeFieldOffsets();
}
Reads non-proxy class descriptor information from given input stream.
The resulting class descriptor is not fully functional; it can only be
used as input to the ObjectInputStream.resolveClass() and
ObjectStreamClass.initNonProxy() methods. |
void setObjFieldValues(Object obj,
Object[] vals) {
fieldRefl.setObjFieldValues(obj, vals);
}
Sets the serializable object fields of object obj using values from
array vals starting at offset 0. It is the responsibility of the caller
to ensure that obj is of the proper type if non-null. |
void setPrimFieldValues(Object obj,
byte[] buf) {
fieldRefl.setPrimFieldValues(obj, buf);
}
Sets the serializable primitive fields of object obj using values
unmarshalled from byte array buf starting at offset 0. It is the
responsibility of the caller to ensure that obj is of the proper type if
non-null. |
public String toString() {
return name + ": static final long serialVersionUID = " +
getSerialVersionUID() + "L;";
}
Return a string describing this ObjectStreamClass. |
void writeNonProxy(ObjectOutputStream out) throws IOException {
out.writeUTF(name);
out.writeLong(getSerialVersionUID());
byte flags = 0;
if (externalizable) {
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
int protocol = out.getProtocolVersion();
if (protocol != ObjectStreamConstants.PROTOCOL_VERSION_1) {
flags |= ObjectStreamConstants.SC_BLOCK_DATA;
}
} else if (serializable) {
flags |= ObjectStreamConstants.SC_SERIALIZABLE;
}
if (hasWriteObjectData) {
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
}
if (isEnum) {
flags |= ObjectStreamConstants.SC_ENUM;
}
out.writeByte(flags);
out.writeShort(fields.length);
for (int i = 0; i < fields.length; i++) {
ObjectStreamField f = fields[i];
out.writeByte(f.getTypeCode());
out.writeUTF(f.getName());
if (!f.isPrimitive()) {
out.writeTypeString(f.getTypeString());
}
}
}
Writes non-proxy class descriptor information to given output stream. |