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 + -
显示快捷键?