objectstreamclass.java

来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 873 行 · 第 1/2 页

JAVA
873
字号
  {outer:    for(int i = 0; i < methods.length; i++)    {	if(methods[i].getName().equals(name) &&	   methods[i].getReturnType() == returnType)	{	    Class[] mp = methods[i].getParameterTypes();	    if(mp.length == params.length)	    {		for(int j = 0; j < mp.length; j++)		{		    if(mp[j] != params[j])		    {			continue outer;		    }		}		final Method m = methods[i];		AccessController.doPrivileged(new PrivilegedAction()		{		    public Object run()		    {			m.setAccessible(true);			return null;		    }		});		return m;	    }	}    }    return null;  }  private void cacheMethods()  {    Method[] methods = forClass().getDeclaredMethods();    readObjectMethod = findMethod(methods, "readObject",				  new Class[] { ObjectInputStream.class },				  Void.TYPE);    readResolveMethod = findMethod(methods, "readResolve",				   new Class[0], Object.class);  }  private ObjectStreamClass(Class cl)  {    uid = 0;    flags = 0;    isProxyClass = Proxy.isProxyClass(cl);    clazz = cl;    cacheMethods();    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      {	final Field serialPersistentFields =	  cl.getDeclaredField("serialPersistentFields");	AccessController.doPrivileged(new PrivilegedAction()	{	    public Object run()	    {		serialPersistentFields.setAccessible(true);		return null;	    }	});	int modifiers = serialPersistentFields.getModifiers();	if (Modifier.isStatic(modifiers)	    && Modifier.isFinal(modifiers)	    && Modifier.isPrivate(modifiers))	  {	    fields = getSerialPersistentFields(cl);	    if (fields != null)	      {		Arrays.sort (fields);		calculateOffsets();		return;	      }	  }      }    catch (NoSuchFieldException ignore)      {      }    catch (IllegalAccessException 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)	{	  final Field f = all_fields[from];	  AccessController.doPrivileged(new PrivilegedAction()	  {	      public Object run()	      {		  f.setAccessible(true);		  return null;	      }	  });	  fields[to] = new ObjectStreamField(all_fields[from]);	  to++;	}    Arrays.sort(fields);    // Make sure we don't have any duplicate field names    // (Sun JDK 1.4.1. throws an Internal Error as well)    for (int i = 1; i < fields.length; i++)      {	if(fields[i - 1].getName().equals(fields[i].getName()))	    throw new InternalError("Duplicate field " + 			fields[i].getName() + " in class " + cl.getName());      }    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.	final Field suid = cl.getDeclaredField("serialVersionUID");	AccessController.doPrivileged(new PrivilegedAction()	{	    public Object run()	    {		suid.setAccessible(true);		return null;	    }	});	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");	    throw e;	  }	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'. It performs some sanity checks before   * returning the real array. Besides, the returned array is a clean   * copy of the original. So it can be modified.   *   * @param clazz Class to retrieve 'serialPersistentFields' from.   * @return The content of 'serialPersistentFields'.   */  private ObjectStreamField[] getSerialPersistentFields(Class clazz)     throws NoSuchFieldException, IllegalAccessException  {    ObjectStreamField[] fieldsArray = null;    ObjectStreamField[] o;    // Use getDeclaredField rather than getField for the same reason    // as above in getDefinedSUID.    Field f = clazz.getDeclaredField("serialPersistentFields");    f.setAccessible(true);    int modifiers = f.getModifiers();    if (!(Modifier.isStatic(modifiers) &&	  Modifier.isFinal(modifiers) &&	  Modifier.isPrivate(modifiers)))      return null;        o = (ObjectStreamField[]) f.get(null);        if (o == null)      return null;    fieldsArray = new ObjectStreamField[ o.length ];    System.arraycopy(o, 0, fieldsArray, 0, o.length);        return fieldsArray;  }  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;  Method readObjectMethod;  Method readResolveMethod;  boolean realClassIsSerializable;  boolean realClassIsExternalizable;  ObjectStreamField[] fieldMapping;  Class firstNonSerializableParent;  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 nameclass 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 signaturesclass 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 + -
显示快捷键?