📄 objectstreamclass.java
字号:
case 'C': case 'S': primFieldSize += 2; break; case 'I': case 'F': primFieldSize += 4; break; case 'D': case 'J': primFieldSize += 8; 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 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -