objectstreamclass.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 677 行 · 第 1/2 页
JAVA
677 行
break;
}
}
for (objectFieldCount = 0; i < fcount; ++ i)
fields[i].setOffset (objectFieldCount++);
}
private ObjectStreamClass (Class cl)
{
uid = 0;
flags = 0;
isProxyClass = Proxy.isProxyClass (cl);
clazz = cl;
name = cl.getName ();
setFlags (cl);
setFields (cl);
// to those class nonserializable, its uid field is 0
if ( (Serializable.class).isAssignableFrom (cl) && !isProxyClass)
uid = getClassUID (cl);
superClass = lookup (cl.getSuperclass ());
}
// Sets bits in flags according to features of CL.
private void setFlags (Class cl)
{
if ((java.io.Externalizable.class).isAssignableFrom (cl))
flags |= ObjectStreamConstants.SC_EXTERNALIZABLE;
else if ((java.io.Serializable.class).isAssignableFrom (cl))
// only set this bit if CL is NOT Externalizable
flags |= ObjectStreamConstants.SC_SERIALIZABLE;
try
{
Method writeMethod = cl.getDeclaredMethod ("writeObject",
writeMethodArgTypes);
int modifiers = writeMethod.getModifiers ();
if (writeMethod.getReturnType () == Void.TYPE
&& Modifier.isPrivate (modifiers)
&& !Modifier.isStatic (modifiers))
flags |= ObjectStreamConstants.SC_WRITE_METHOD;
}
catch (NoSuchMethodException oh_well)
{}
}
// Sets fields to be a sorted array of the serializable fields of
// clazz.
private void setFields (Class cl)
{
if (! isSerializable () || isExternalizable ())
{
fields = NO_FIELDS;
return;
}
try
{
Field serialPersistentFields
= cl.getDeclaredField ("serialPersistentFields");
serialPersistentFields.setAccessible(true);
int modifiers = serialPersistentFields.getModifiers ();
if (Modifier.isStatic (modifiers)
&& Modifier.isFinal (modifiers)
&& Modifier.isPrivate (modifiers))
{
fields = getSerialPersistentFields (cl);
Arrays.sort (fields);
calculateOffsets ();
return;
}
}
catch (NoSuchFieldException ignore)
{}
int num_good_fields = 0;
Field[] all_fields = cl.getDeclaredFields ();
int modifiers;
// set non-serializable fields to null in all_fields
for (int i=0; i < all_fields.length; i++)
{
modifiers = all_fields[i].getModifiers ();
if (Modifier.isTransient (modifiers)
|| Modifier.isStatic (modifiers))
all_fields[i] = null;
else
num_good_fields++;
}
// make a copy of serializable (non-null) fields
fields = new ObjectStreamField[ num_good_fields ];
for (int from=0, to=0; from < all_fields.length; from++)
if (all_fields[from] != null)
{
Field f = all_fields[from];
fields[to] = new ObjectStreamField (f.getName (), f.getType ());
to++;
}
Arrays.sort (fields);
calculateOffsets ();
}
// Returns the serial version UID defined by class, or if that
// isn't present, calculates value of serial version UID.
private long getClassUID (Class cl)
{
try
{
// Use getDeclaredField rather than getField, since serialVersionUID
// may not be public AND we only want the serialVersionUID of this
// class, not a superclass or interface.
Field suid = cl.getDeclaredField ("serialVersionUID");
suid.setAccessible(true);
int modifiers = suid.getModifiers ();
if (Modifier.isStatic (modifiers)
&& Modifier.isFinal (modifiers)
&& suid.getType() == Long.TYPE)
return suid.getLong (null);
}
catch (NoSuchFieldException ignore)
{}
catch (IllegalAccessException ignore)
{}
// cl didn't define serialVersionUID, so we have to compute it
try
{
MessageDigest md;
try
{
md = MessageDigest.getInstance ("SHA");
}
catch (NoSuchAlgorithmException e)
{
// If a provider already provides SHA, use it; otherwise, use this.
Gnu gnuProvider = new Gnu();
Security.addProvider(gnuProvider);
md = MessageDigest.getInstance ("SHA");
}
DigestOutputStream digest_out =
new DigestOutputStream (nullOutputStream, md);
DataOutputStream data_out = new DataOutputStream (digest_out);
data_out.writeUTF (cl.getName ());
int modifiers = cl.getModifiers ();
// just look at interesting bits
modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL
| Modifier.INTERFACE | Modifier.PUBLIC);
data_out.writeInt (modifiers);
// Pretend that an array has no interfaces, because when array
// serialization was defined (JDK 1.1), arrays didn't have it.
if (! cl.isArray ())
{
Class[] interfaces = cl.getInterfaces ();
Arrays.sort (interfaces, interfaceComparator);
for (int i=0; i < interfaces.length; i++)
data_out.writeUTF (interfaces[i].getName ());
}
Field field;
Field[] fields = cl.getDeclaredFields ();
Arrays.sort (fields, memberComparator);
for (int i=0; i < fields.length; i++)
{
field = fields[i];
modifiers = field.getModifiers ();
if (Modifier.isPrivate (modifiers)
&& (Modifier.isStatic (modifiers)
|| Modifier.isTransient (modifiers)))
continue;
data_out.writeUTF (field.getName ());
data_out.writeInt (modifiers);
data_out.writeUTF (TypeSignature.getEncodingOfClass (field.getType ()));
}
// write class initializer method if present
if ( VMObjectStreamClass.hasClassInitializer (cl))
{
data_out.writeUTF ("<clinit>");
data_out.writeInt (Modifier.STATIC);
data_out.writeUTF ("()V");
}
Constructor constructor;
Constructor[] constructors = cl.getDeclaredConstructors ();
Arrays.sort (constructors, memberComparator);
for (int i=0; i < constructors.length; i++)
{
constructor = constructors[i];
modifiers = constructor.getModifiers ();
if (Modifier.isPrivate (modifiers))
continue;
data_out.writeUTF ("<init>");
data_out.writeInt (modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF (
TypeSignature.getEncodingOfConstructor (constructor).replace ('/','.'));
}
Method method;
Method[] methods = cl.getDeclaredMethods ();
Arrays.sort (methods, memberComparator);
for (int i=0; i < methods.length; i++)
{
method = methods[i];
modifiers = method.getModifiers ();
if (Modifier.isPrivate (modifiers))
continue;
data_out.writeUTF (method.getName ());
data_out.writeInt (modifiers);
// the replacement of '/' with '.' was needed to make computed
// SUID's agree with those computed by JDK
data_out.writeUTF (
TypeSignature.getEncodingOfMethod (method).replace ('/', '.'));
}
data_out.close ();
byte[] sha = md.digest ();
long result = 0;
int len = sha.length < 8 ? sha.length : 8;
for (int i=0; i < len; i++)
result += (long)(sha[i] & 0xFF) << (8 * i);
return result;
}
catch (NoSuchAlgorithmException e)
{
throw new RuntimeException ("The SHA algorithm was not found to use in computing the Serial Version UID for class "
+ cl.getName (), e);
}
catch (IOException ioe)
{
throw new RuntimeException (ioe);
}
}
// Returns the value of CLAZZ's private static final field named
// `serialPersistentFields'.
private ObjectStreamField[] getSerialPersistentFields (Class clazz)
{
ObjectStreamField[] o = null;
try
{
// Use getDeclaredField rather than getField for the same reason
// as above in getDefinedSUID.
Field f = clazz.getDeclaredField ("getSerialPersistentFields");
f.setAccessible(true);
o = (ObjectStreamField[])f.get (null);
}
catch (java.lang.NoSuchFieldException e)
{
}
catch (java.lang.IllegalAccessException e)
{
}
return o;
}
public static final ObjectStreamField[] NO_FIELDS = {};
private static Hashtable classLookupTable = new Hashtable ();
private static final NullOutputStream nullOutputStream = new NullOutputStream ();
private static final Comparator interfaceComparator = new InterfaceComparator ();
private static final Comparator memberComparator = new MemberComparator ();
private static final
Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class };
private ObjectStreamClass superClass;
private Class clazz;
private String name;
private long uid;
private byte flags;
// this field is package protected so that ObjectInputStream and
// ObjectOutputStream can access it directly
ObjectStreamField[] fields;
// these are accessed by ObjectIn/OutputStream
int primFieldSize = -1; // -1 if not yet calculated
int objectFieldCount;
boolean isProxyClass = false;
// This is probably not necessary because this class is special cased already
// but it will avoid showing up as a discrepancy when comparing SUIDs.
private static final long serialVersionUID = -6120832682080437368L;
}
// interfaces are compared only by name
class InterfaceComparator implements Comparator
{
public int compare (Object o1, Object o2)
{
return ((Class)o1).getName ().compareTo (((Class)o2).getName ());
}
}
// Members (Methods and Constructors) are compared first by name,
// conflicts are resolved by comparing type signatures
class MemberComparator implements Comparator
{
public int compare (Object o1, Object o2)
{
Member m1 = (Member)o1;
Member m2 = (Member)o2;
int comp = m1.getName ().compareTo (m2.getName ());
if (comp == 0)
return TypeSignature.getEncodingOfMember (m1).
compareTo (TypeSignature.getEncodingOfMember (m2));
else
return comp;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?