📄 objectstreamclass.java
字号:
pf.setAccessible(true); // serial bug 7; need to find if the field is of type // java.io.ObjectStreamField java.io.ObjectStreamField[] f = (java.io.ObjectStreamField[])pf.get(cl); int mods = pf.getModifiers(); if ((Modifier.isPrivate(mods)) && (Modifier.isStatic(mods)) && (Modifier.isFinal(mods))) { fields = (ObjectStreamField[])translateFields((Object[])pf.get(cl)); } } catch (NoSuchFieldException e) { fields = null; } catch (IllegalAccessException e) { fields = null; } catch (IllegalArgumentException e) { fields = null; } catch (ClassCastException e) { /* Thrown if a field serialPersistentField exists * but it is not of type ObjectStreamField. */ fields = null; } if (fields == null) { /* Get all of the declared fields for this * Class. setAccessible on all fields so they * can be accessed later. Create a temporary * ObjectStreamField array to hold each * non-static, non-transient field. Then copy the * temporary array into an array of the correct * 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 com.sun.corba.se.internal.io.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 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 = _computeSerialVersionUID(cl); // SerialBug 2: should be computed after writeObject // actualSuid = computeStructuralUID(cl); } } catch (NoSuchFieldException ex) { suid = _computeSerialVersionUID(cl); // SerialBug 2: should be computed after writeObject // actualSuid = computeStructuralUID(cl); } catch (IllegalAccessException ex) { suid = _computeSerialVersionUID(cl); } } writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl, "writeReplace", noTypesList, Object.class); readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl, "readResolve", noTypesList, Object.class); /* 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; } }); } // This call depends on a lot of information computed above! actualSuid = ObjectStreamClass.computeStructuralUID(this, cl); // This must be done last. initialized = true; } } /* * Create an empty ObjectStreamClass for a class about to be read. * This is separate from read so ObjectInputStream can assign the * wire handle early, before any nested ObjectStreamClass might * be read. */ ObjectStreamClass(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 = Class.forName("com.sun.corba.se.internal.io.ObjectStreamField"); 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(); } } /* * Set the class this version descriptor matches. * The base class name and serializable hash must match. * Fill in the reflected Fields that will be used * for reading. */ final void setClass(Class cl) throws InvalidClassException { if (cl == null) { localClassDesc = null; ofClass = null; computeFieldInfo(); return; } localClassDesc = lookupInternal(cl); if (localClassDesc == null) throw new InvalidClassException(cl.getName(), "Local class not compatible"); if (suid != localClassDesc.suid) { /* Check for exceptional cases that allow mismatched suid. */ /* Allow adding Serializable or Externalizable * to a later release of the class. */ boolean addedSerialOrExtern = isNonSerializable() || localClassDesc.isNonSerializable(); /* Disregard the serialVersionUID of an array * when name and cl.Name differ. If resolveClass() returns * an array with a different package name, * the serialVersionUIDs will not match since the fully * qualified array class is used in the * computation of the array's serialVersionUID. There is * no way to set a permanent serialVersionUID for an array type. */ boolean arraySUID = (cl.isArray() && ! cl.getName().equals(name)); if (! arraySUID && ! addedSerialOrExtern ) { throw new InvalidClassException(cl.getName(), "Local class not compatible:" + " stream classdesc serialVersionUID=" + suid + " local class serialVersionUID=" + localClassDesc.suid); } } /* compare the class names, stripping off package names. */ if (! compareClassNames(name, cl.getName(), '.')) throw new InvalidClassException(cl.getName(), "Incompatible local class name. " + "Expected class name compatible with " + name); /* * Test that both implement either serializable or externalizable. */ // The next check is more generic, since it covers the // Proxy case, the JDK 1.3 serialization code has // both checks //if ((serializable && localClassDesc.externalizable) || // (externalizable && localClassDesc.serializable)) // throw new InvalidClassException(localCl.getName(), // "Serializable is incompatible with Externalizable"); if ((serializable != localClassDesc.serializable) || (externalizable != localClassDesc.externalizable) || (!serializable && !externalizable)) throw new InvalidClassException(cl.getName(), "Serialization incompatible with Externalization"); /* Set up the reflected Fields in the class where the value of each * field in this descriptor should be stored. * Each field in this ObjectStreamClass (the source) is located (by * name) in the ObjectStreamClass of the class(the destination). * In the usual (non-versioned case) the field is in both * descriptors and the types match, so the reflected Field is copied. * If the type does not match, a InvalidClass exception is thrown. * If the field is not present in the class, the reflected Field * remains null so the field will be read but discarded. * If extra fields are present in the class they are ignored. Their * values will be set to the default value by the object allocator. * Both the src and dest field list are sorted by type and name. */ ObjectStreamField[] destfield = (ObjectStreamField[])localClassDesc.fields; ObjectStreamField[] srcfield = (ObjectStreamField[])fields; int j = 0; nextsrc: for (int i = 0; i < srcfield.length; i++ ) { /* Find this field in the dest*/ for (int k = j; k < destfield.length; k++) { if (srcfield[i].getName().equals(destfield[k].getName())) { /* found match */ if (srcfield[i].isPrimitive() && !srcfield[i].typeEquals(destfield[k])) { throw new InvalidClassException(cl.getName(), "The type of field " + srcfield[i].getName() + " of class " + name + " is incompatible."); } /* Skip over any fields in the dest that are not in the src */ j = k; srcfield[i].setField(destfield[j].getField()); // go on to the next source field continue nextsrc; } } } /* Set up field data for use while reading from the input stream. */ computeFieldInfo(); /* Remember the class this represents */ ofClass = cl; /* get the cache of these methods from the local class * implementation. */ readObjectMethod = localClassDesc.readObjectMethod; readResolveObjectMethod = localClassDesc.readResolveObjectMethod; /* 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 = ObjectStreamClass.getDeclaredMethod(cl,"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) { }*****/ } /* 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 '/'.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -