📄 objectstreamclass_1_3_1.java
字号:
/* * @(#)ObjectStreamClass_1_3_1.java 1.6 04/01/12 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * Licensed Materials - Property of IBM * RMI-IIOP v1.0 * Copyright IBM Corp. 1998 1999 All Rights Reserved * * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */package com.sun.corba.se.impl.orbutil;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.security.DigestOutputStream;import java.security.AccessController;import java.security.PrivilegedExceptionAction;import java.security.PrivilegedActionException;import java.security.PrivilegedAction;import java.lang.reflect.Modifier;import java.lang.reflect.Array;import java.lang.reflect.Field;import java.lang.reflect.Member;import java.lang.reflect.Method;import java.lang.reflect.Constructor;import java.lang.reflect.Proxy;import java.lang.reflect.InvocationTargetException;import java.io.IOException;import java.io.DataOutputStream;import java.io.ByteArrayOutputStream;import java.io.InvalidClassException;import java.io.Serializable;import java.util.Arrays;import java.util.Comparator;import java.util.Hashtable;import org.omg.CORBA.ValueMember;import com.sun.corba.se.impl.io.ValueUtility;import com.sun.corba.se.impl.io.ObjectStreamClass;/** * This is duplicated here to preserve the JDK 1.3.1FCS behavior * of calculating the OMG hash code incorrectly when serialPersistentFields * is used, but some of the fields no longer exist in the class itself. * * We have to duplicate it since we aren't allowed to modify the * com.sun.corba.se.impl.io version further, and can't make it * public outside of its package for security reasons. *//** * A ObjectStreamClass_1_3_1 describes a class that can be serialized to a stream * or a class that was serialized to a stream. It contains the name * and the serialVersionUID of the class. * <br> * The ObjectStreamClass_1_3_1 for a specific class loaded in this Java VM can * be found using the lookup method. * * @author Roger Riggs * @(#)ObjectStreamClass_1_3_1.java 1.17 99/06/07 * @since JDK1.1 */public class ObjectStreamClass_1_3_1 implements java.io.Serializable { public static final long kDefaultUID = -1; private static Object noArgsList[] = {}; private static Class noTypesList[] = {}; private static Hashtable translatedFields; /** Find the descriptor for a class that can be serialized. Null * is returned if the specified class does not implement * java.io.Serializable or java.io.Externalizable. */ static final ObjectStreamClass_1_3_1 lookup(Class cl) { ObjectStreamClass_1_3_1 desc = lookupInternal(cl); if (desc.isSerializable() || desc.isExternalizable()) return desc; return null; } /* * Find the class descriptor for the specified class. * Package access only so it can be called from ObjectIn/OutStream. */ static ObjectStreamClass_1_3_1 lookupInternal(Class cl) { /* Synchronize on the hashtable so no two threads will do * this at the same time. */ ObjectStreamClass_1_3_1 desc = null; synchronized (descriptorFor) { /* Find the matching descriptor if it already known */ desc = findDescriptorFor(cl); if (desc != null) { return desc; } /* Check if it's serializable */ boolean serializable = classSerializable.isAssignableFrom(cl); /* If the class is only Serializable, * lookup the descriptor for the superclass. */ ObjectStreamClass_1_3_1 superdesc = null; if (serializable) { Class superclass = cl.getSuperclass(); if (superclass != null) superdesc = lookup(superclass); } /* Check if its' externalizable. * If it's Externalizable, clear the serializable flag. * Only one or the other may be set in the protocol. */ boolean externalizable = false; if (serializable) { externalizable = ((superdesc != null) && superdesc.isExternalizable()) || classExternalizable.isAssignableFrom(cl); if (externalizable) { serializable = false; } } /* Create a new version descriptor, * it put itself in the known table. */ desc = new ObjectStreamClass_1_3_1(cl, superdesc, serializable, externalizable); } desc.init(); return desc; } /** * The name of the class described by this descriptor. */ public final String getName() { return name; } /** * Return the serialVersionUID for this class. * The serialVersionUID defines a set of classes all with the same name * that have evolved from a common root class and agree to be serialized * and deserialized using a common format. */ public static final long getSerialVersionUID( java.lang.Class clazz) { ObjectStreamClass_1_3_1 theosc = ObjectStreamClass_1_3_1.lookup( clazz ); if( theosc != null ) { return theosc.getSerialVersionUID( ); } return 0; } /** * Return the serialVersionUID for this class. * The serialVersionUID defines a set of classes all with the same name * that have evolved from a common root class and agree to be serialized * and deserialized using a common format. */ public final long getSerialVersionUID() { return suid; } /** * Return the serialVersionUID string for this class. * The serialVersionUID defines a set of classes all with the same name * that have evolved from a common root class and agree to be serialized * and deserialized using a common format. */ public final String getSerialVersionUIDStr() { if (suidStr == null) suidStr = Long.toHexString(suid).toUpperCase(); return suidStr; } /** * Return the actual (computed) serialVersionUID for this class. */ public static final long getActualSerialVersionUID( java.lang.Class clazz ) { ObjectStreamClass_1_3_1 theosc = ObjectStreamClass_1_3_1.lookup( clazz ); if( theosc != null ) { return theosc.getActualSerialVersionUID( ); } return 0; } /** * Return the actual (computed) serialVersionUID for this class. */ public final long getActualSerialVersionUID() { return actualSuid; } /** * Return the actual (computed) serialVersionUID for this class. */ public final String getActualSerialVersionUIDStr() { if (actualSuidStr == null) actualSuidStr = Long.toHexString(actualSuid).toUpperCase(); return actualSuidStr; } /** * Return the class in the local VM that this version is mapped to. * Null is returned if there is no corresponding local class. */ public final Class forClass() { return ofClass; } /** * Return an array of the fields of this serializable class. * @return an array containing an element for each persistent * field of this class. Returns an array of length zero if * there are no fields. * @since JDK1.2 */ public ObjectStreamField[] getFields() { // Return a copy so the caller can't change the fields. if (fields.length > 0) { ObjectStreamField[] dup = new ObjectStreamField[fields.length]; System.arraycopy(fields, 0, dup, 0, fields.length); return dup; } else { return fields; } } public boolean hasField(ValueMember field){ for (int i = 0; i < fields.length; i++){ try{ if (fields[i].getName().equals(field.name)) { if (fields[i].getSignature().equals(ValueUtility.getSignature(field))) return true; } } catch(Throwable t){} } return false; } /* Avoid unnecessary allocations. */ final ObjectStreamField[] getFieldsNoCopy() { return fields; } /** * Get the field of this class by name. * @return The ObjectStreamField object of the named field or null if there * is no such named field. */ public final ObjectStreamField getField(String name) { /* Binary search of fields by name. */ for (int i = fields.length-1; i >= 0; i--) { if (name.equals(fields[i].getName())) { return fields[i]; } } return null; } public Serializable writeReplace(Serializable value) { if (writeReplaceObjectMethod != null) { try { return (Serializable) writeReplaceObjectMethod.invoke(value,noArgsList); } catch(Throwable t) { throw new RuntimeException(t.getMessage()); } } else return value; } public Object readResolve(Object value) { if (readResolveObjectMethod != null) { try { return readResolveObjectMethod.invoke(value,noArgsList); } catch(Throwable t) { throw new RuntimeException(t.getMessage()); } } else return value; } /** * Return a string describing this ObjectStreamClass_1_3_1. */ public final String toString() { StringBuffer sb = new StringBuffer(); sb.append(name); sb.append(": static final long serialVersionUID = "); sb.append(Long.toString(suid)); sb.append("L;"); return sb.toString(); } /* * Create a new ObjectStreamClass_1_3_1 from a loaded class. * Don't call this directly, call lookup instead. */ private ObjectStreamClass_1_3_1(java.lang.Class cl, ObjectStreamClass_1_3_1 superdesc, boolean serial, boolean extern) { ofClass = cl; /* created from this class */ if (Proxy.isProxyClass(cl)) { forProxyClass = true; } name = cl.getName(); superclass = superdesc; serializable = serial; if (!forProxyClass) { // proxy classes are never externalizable externalizable = extern; } /* * Enter this class in the table of known descriptors. * Otherwise, when the fields are read it may recurse * trying to find the descriptor for itself. */ insertDescriptorFor(this); /* * The remainder of initialization occurs in init(), which is called * after the lock on the global class descriptor table has been * released. */ } /* * Initialize class descriptor. This method is only invoked on class * descriptors created via calls to lookupInternal(). This method is kept * separate from the ObjectStreamClass_1_3_1 constructor so that lookupInternal * does not have to hold onto a global class descriptor table lock while the * class descriptor is being initialized (see bug 4165204). */ private void init() { synchronized (lock) { final Class cl = ofClass; if (fields != null) // already initialized return; if (!serializable || externalizable || forProxyClass || name.equals("java.lang.String")) { fields = NO_FIELDS; } else if (serializable) { /* Ask for permission to override field access checks. */ AccessController.doPrivileged(new PrivilegedAction() { public Object run() { /* Fill in the list of persistent fields. * If it is declared, use the declared serialPersistentFields. * Otherwise, extract the fields from the class itself. */ try { Field pf = cl.getDeclaredField("serialPersistentFields"); // serial bug 7; the serialPersistentFields were not // being read and stored as Accessible bit was not set 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -