📄 objectstreamclass_1_3_1.java
字号:
* size once the number of fields is known. */ Field[] actualfields = cl.getDeclaredFields(); int numFields = 0; ObjectStreamField[] tempFields = new ObjectStreamField[actualfields.length]; for (int i = 0; i < actualfields.length; i++) { int modifiers = actualfields[i].getModifiers(); if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) { tempFields[numFields++] = new ObjectStreamField(actualfields[i]); } } fields = new ObjectStreamField[numFields]; System.arraycopy(tempFields, 0, fields, 0, numFields); } else { // For each declared persistent field, look for an actual // reflected Field. If there is one, make sure it's the correct // type and cache it in the ObjectStreamClass_1_3_1 for that field. for (int j = fields.length-1; j >= 0; j--) { try { Field reflField = cl.getDeclaredField(fields[j].getName()); if (fields[j].getType() == reflField.getType()) { // reflField.setAccessible(true); fields[j].setField(reflField); } } catch (NoSuchFieldException e) { // Nothing to do } } } return null; } }); if (fields.length > 1) Arrays.sort(fields); /* Set up field data for use while writing using the API api. */ computeFieldInfo(); } /* Get the serialVersionUID from the class. * It uses the access override mechanism so make sure * the field objects is only used here. * * NonSerializable classes have a serialVerisonUID of 0L. */ if (isNonSerializable()) { suid = 0L; } else { // Lookup special Serializable members using reflection. AccessController.doPrivileged(new PrivilegedAction() { public Object run() { if (forProxyClass) { // proxy classes always have serialVersionUID of 0L suid = 0L; } else { try { final Field f = cl.getDeclaredField("serialVersionUID"); int mods = f.getModifiers(); // SerialBug 5: static final SUID should be read if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) { f.setAccessible(true); suid = f.getLong(cl); // get rid of native code // suid = getSerialVersionUIDField(cl); // SerialBug 2: should be computed after writeObject // actualSuid = computeStructuralUID(cl); } else { suid = ObjectStreamClass.getSerialVersionUID(cl); // SerialBug 2: should be computed after writeObject // actualSuid = computeStructuralUID(cl); } } catch (NoSuchFieldException ex) { suid = ObjectStreamClass.getSerialVersionUID(cl); // SerialBug 2: should be computed after writeObject // actualSuid = computeStructuralUID(cl); } catch (IllegalAccessException ex) { suid = ObjectStreamClass.getSerialVersionUID(cl); } } try { writeReplaceObjectMethod = cl.getDeclaredMethod("writeReplace", noTypesList); if (Modifier.isStatic(writeReplaceObjectMethod.getModifiers())) { writeReplaceObjectMethod = null; } else { writeReplaceObjectMethod.setAccessible(true); } } catch (NoSuchMethodException e2) { } try { readResolveObjectMethod = cl.getDeclaredMethod("readResolve", noTypesList); if (Modifier.isStatic(readResolveObjectMethod.getModifiers())) { readResolveObjectMethod = null; } else { readResolveObjectMethod.setAccessible(true); } } catch (NoSuchMethodException e2) { } /* Cache lookup of writeObject and readObject for * Serializable classes. (Do not lookup for * Externalizable) */ if (serializable && !forProxyClass) { /* Look for the writeObject method * Set the accessible flag on it here. ObjectOutputStream * will call it as necessary. */ try { Class[] args = {java.io.ObjectOutputStream.class}; writeObjectMethod = cl.getDeclaredMethod("writeObject", args); hasWriteObjectMethod = true; int mods = writeObjectMethod.getModifiers(); // Method must be private and non-static if (!Modifier.isPrivate(mods) || Modifier.isStatic(mods)) { writeObjectMethod = null; hasWriteObjectMethod = false; } } catch (NoSuchMethodException e) { } /* Look for the readObject method * set the access override and save the reference for * ObjectInputStream so it can all the method directly. */ try { Class[] args = {java.io.ObjectInputStream.class}; readObjectMethod = cl.getDeclaredMethod("readObject", args); int mods = readObjectMethod.getModifiers(); // Method must be private and non-static if (!Modifier.isPrivate(mods) || Modifier.isStatic(mods)) { readObjectMethod = null; } } catch (NoSuchMethodException e) { } // Compute the structural UID. This must be done after the // calculation for writeObject. Fixed 4/20/2000, eea1 // SerialBug 2: to have correct value in RepId } return null; } }); } actualSuid = computeStructuralUID(this, cl); } } /* * Create an empty ObjectStreamClass_1_3_1 for a class about to be read. * This is separate from read so ObjectInputStream can assign the * wire handle early, before any nested ObjectStreamClass_1_3_1 might * be read. */ ObjectStreamClass_1_3_1(String n, long s) { name = n; suid = s; superclass = null; } private static Object[] translateFields(Object objs[]) throws NoSuchFieldException { try{ java.io.ObjectStreamField fields[] = (java.io.ObjectStreamField[])objs; Object translation[] = null; if (translatedFields == null) translatedFields = new Hashtable(); translation = (Object[])translatedFields.get(fields); if (translation != null) return translation; else { Class osfClass = com.sun.corba.se.impl.orbutil.ObjectStreamField.class; translation = (Object[])java.lang.reflect.Array.newInstance(osfClass, objs.length); Object arg[] = new Object[2]; Class types[] = {String.class, Class.class}; Constructor constructor = osfClass.getDeclaredConstructor(types); for (int i = fields.length -1; i >= 0; i--){ arg[0] = fields[i].getName(); arg[1] = fields[i].getType(); translation[i] = constructor.newInstance(arg); } translatedFields.put(fields, translation); } return (Object[])translation; } catch(Throwable t){ throw new NoSuchFieldException(); } } /* Compare the base class names of streamName and localName. * * @return Return true iff the base class name compare. * @parameter streamName Fully qualified class name. * @parameter localName Fully qualified class name. * @parameter pkgSeparator class names use either '.' or '/'. * * Only compare base class name to allow package renaming. */ static boolean compareClassNames(String streamName, String localName, char pkgSeparator) { /* compare the class names, stripping off package names. */ int streamNameIndex = streamName.lastIndexOf(pkgSeparator); if (streamNameIndex < 0) streamNameIndex = 0; int localNameIndex = localName.lastIndexOf(pkgSeparator); if (localNameIndex < 0) localNameIndex = 0; return streamName.regionMatches(false, streamNameIndex, localName, localNameIndex, streamName.length() - streamNameIndex); } /* * Compare the types of two class descriptors. * They match if they have the same class name and suid */ final boolean typeEquals(ObjectStreamClass_1_3_1 other) { return (suid == other.suid) && compareClassNames(name, other.name, '.'); } /* * Return the superclass descriptor of this descriptor. */ final void setSuperclass(ObjectStreamClass_1_3_1 s) { superclass = s; } /* * Return the superclass descriptor of this descriptor. */ final ObjectStreamClass_1_3_1 getSuperclass() { return superclass; } /* * Return whether the class has a writeObject method */ final boolean hasWriteObject() { return hasWriteObjectMethod; } final boolean isCustomMarshaled() { return (hasWriteObject() || isExternalizable()); } /* * Return true if all instances of 'this' Externalizable class * are written in block-data mode from the stream that 'this' was read * from. <p> * * In JDK 1.1, all Externalizable instances are not written * in block-data mode. * In JDK 1.2, all Externalizable instances, by default, are written * in block-data mode and the Externalizable instance is terminated with * tag TC_ENDBLOCKDATA. Change enabled the ability to skip Externalizable * instances. * * IMPLEMENTATION NOTE: * This should have been a mode maintained per stream; however, * for compatibility reasons, it was only possible to record * this change per class. All Externalizable classes within * a given stream should either have this mode enabled or * disabled. This is enforced by not allowing the PROTOCOL_VERSION * of a stream to he changed after any objects have been written. * * @see ObjectOutputStream#useProtocolVersion * @see ObjectStreamConstants#PROTOCOL_VERSION_1 * @see ObjectStreamConstants#PROTOCOL_VERSION_2 * * @since JDK 1.2 */ boolean hasExternalizableBlockDataMode() { return hasExternalizableBlockData; } /* * Return the ObjectStreamClass_1_3_1 of the local class this one is based on. */ final ObjectStreamClass_1_3_1 localClassDescriptor() { return localClassDesc; } /* * Get the Serializability of the class. */ boolean isSerializable() { return serializable; } /* * Get the externalizability of the class. */ boolean isExternalizable() { return externalizable; } boolean isNonSerializable() { return ! (externalizable || serializable); } /* * Calculate the size of the array needed to store primitive data and the * number of object references to read when reading from the input * stream. */ private void computeFieldInfo() { primBytes = 0; objFields = 0; for (int i = 0; i < fields.length; i++ ) { switch (fields[i].getTypeCode()) { case 'B': case 'Z': primBytes += 1; break; case 'C': case 'S': primBytes += 2; break; case 'I': case 'F': primBytes += 4; break; case 'J': case 'D' : primBytes += 8; break; case 'L': case '[': objFields += 1; break; } } } private static long computeStructuralUID(ObjectStreamClass_1_3_1 osc, Class cl) { ByteArrayOutputStream devnull = new ByteArrayOutputStream(512); long h = 0; try { if ((!java.io.Serializable.class.isAssignableFrom(cl)) || (cl.isInterface())){ return 0; } if (java.io.Externalizable.class.isAssignableFrom(cl)) { return 1; } MessageDigest md = MessageDigest.getInstance("SHA"); DigestOutputStream mdo = new DigestOutputStream(devnull, md); DataOutputStream data = new DataOutputStream(mdo); // Get SUID of parent Class parent = cl.getSuperclass(); if ((parent != null)) // SerialBug 1; acc. to spec the one for // java.lang.object // should be computed and put // && (parent != java.lang.Object.class)) { //data.writeLong(computeSerialVersionUID(null,parent)); data.writeLong(computeStructuralUID(lookup(parent), parent)); } if (osc.hasWriteObject()) data.writeInt(2); else data.writeInt(1); /* Sort the field names to get a deterministic order */ // Field[] field = ObjectStreamClass_1_3_1.getDeclaredFields(cl); ObjectStreamField[] fields = osc.getFields(); // Must make sure that the Field array we allocate // below is exactly the right size. Bug fix for // 4397133. int numNonNullFields = 0; for (int i = 0; i < fields.length; i++) if (fields[i].getField() != null) numNonNullFields++; Field [] field = new java.lang.reflect.Field[numNonNullFields]; for (int i = 0, fieldNum = 0; i < fields.length; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -