⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objectstreamclass.java

📁 java jdk 1.4的源码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
     *     * 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 other) {	return (suid == other.suid) &&	    compareClassNames(name, other.name, '.');    }    /*     * Return the superclass descriptor of this descriptor.     */    final void setSuperclass(ObjectStreamClass s) {	superclass = s;    }    /*     * Return the superclass descriptor of this descriptor.     */    final ObjectStreamClass 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 ObjectOuputStream#useProtocolVersion     * @see ObjectStreamConstants#PROTOCOL_VERSION_1     * @see ObjectStreamConstants#PROTOCOL_VERSION_2     *     * @since JDK 1.2     */    boolean hasExternalizableBlockDataMode() {	return hasExternalizableBlockData;    }    /*     * Return the ObjectStreamClass of the local class this one is based on.     */    final ObjectStreamClass 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;	    }	}    }    /*     * Compute a hash for the specified class.  Incrementally add     * items to the hash accumulating in the digest stream.     * Fold the hash into a long.  Use the SHA secure hash function.     */    private static long _computeSerialVersionUID(Class cl) {	ByteArrayOutputStream devnull = new ByteArrayOutputStream(512);	long h = 0;	try {	    MessageDigest md = MessageDigest.getInstance("SHA");	    DigestOutputStream mdo = new DigestOutputStream(devnull, md);	    DataOutputStream data = new DataOutputStream(mdo);	    data.writeUTF(cl.getName());	    int classaccess = cl.getModifiers();	    classaccess &= (Modifier.PUBLIC | Modifier.FINAL |			    Modifier.INTERFACE | Modifier.ABSTRACT);	    /* Workaround for javac bug that only set ABSTRACT for	     * interfaces if the interface had some methods.	     * The ABSTRACT bit reflects that the number of methods > 0.	     * This is required so correct hashes can be computed	     * for existing class files.	     * Previously this hack was previously present in the VM.	     */            Method[] method = cl.getDeclaredMethods();	    if ((classaccess & Modifier.INTERFACE) != 0) {		classaccess &= (~Modifier.ABSTRACT);		if (method.length > 0) {		    classaccess |= Modifier.ABSTRACT;		}	    }	    data.writeInt(classaccess);	    /*	     * Get the list of interfaces supported,	     * Accumulate their names their names in Lexical order	     * and add them to the hash	     */            if (!cl.isArray()) {                /* In 1.2fcs, getInterfaces() was modified to return                 * {java.lang.Cloneable, java.io.Serializable} when                 * called on array classes.  These values would upset                 * the computation of the hash, so we explicitly omit                 * them from its computation.                 */	        Class interfaces[] = cl.getInterfaces();	        Arrays.sort(interfaces, compareClassByName);	        for (int i = 0; i < interfaces.length; i++) {		    data.writeUTF(interfaces[i].getName());	        }	    }	    /* Sort the field names to get a deterministic order */            Field[] field = cl.getDeclaredFields();	    Arrays.sort(field, compareMemberByName);	    for (int i = 0; i < field.length; i++) {		Field f = field[i];		/* Include in the hash all fields except those that are		 * private transient and private static.		 */		int m = f.getModifiers();		if (Modifier.isPrivate(m) &&		    (Modifier.isTransient(m) || Modifier.isStatic(m)))		    continue;		data.writeUTF(f.getName());		data.writeInt(m);		data.writeUTF(getSignature(f.getType()));	    }	    if (hasStaticInitializer(cl)) {		data.writeUTF("<clinit>");		data.writeInt(Modifier.STATIC); // TBD: what modifiers does it have		data.writeUTF("()V");	    }	    /*	     * Get the list of constructors including name and signature	     * Sort lexically, add all except the private constructors	     * to the hash with their access flags	     */	    MethodSignature[] constructors =		MethodSignature.removePrivateAndSort(cl.getDeclaredConstructors());	    for (int i = 0; i < constructors.length; i++) {		MethodSignature c = constructors[i];		String mname = "<init>";		String desc = c.signature;		desc = desc.replace('/', '.');		data.writeUTF(mname);		data.writeInt(c.member.getModifiers());		data.writeUTF(desc);	    }	    /* Include in the hash all methods except those that are	     * private transient and private static.	     */	    MethodSignature[] methods =		MethodSignature.removePrivateAndSort(method);	    for (int i = 0; i < methods.length; i++ ) {		MethodSignature m = methods[i];		String desc = m.signature;		desc = desc.replace('/', '.');		data.writeUTF(m.member.getName());		data.writeInt(m.member.getModifiers());		data.writeUTF(desc);	    }	    /* Compute the hash value for this class.	     * Use only the first 64 bits of the hash.	     */	    data.flush();	    byte hasharray[] = md.digest();	    for (int i = 0; i < Math.min(8, hasharray.length); i++) {		h += (long)(hasharray[i] & 255) << (i * 8);	    }	} catch (IOException ignore) {	    /* can't happen, but be deterministic anyway. */	    h = -1;	} catch (NoSuchAlgorithmException complain) {	    throw new SecurityException(complain.getMessage());	}	return h;    }    private static long computeStructuralUID(com.sun.corba.se.internal.io.ObjectStreamClass 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);            // CORBA formal 00-11-03 10.6.2:  For each field of the            // class that is mapped to IDL, sorted lexicographically            // by Java field name, in increasing order...            ObjectStreamField[] field = osc.getFields();            if (field.length > 1) {                Arrays.sort(field, compareObjStrFieldsByName);            }            // ...Java field name in UTF encoding, field            // descriptor, as defined by the JVM spec...            for (int i = 0; i < field.length; i++) {                data.writeUTF(field[i].getName());                data.writeUTF(field[i].getSignature());            }				    /* Compute the hash value for this class.	     * Use only the first 64 bits of the hash.	     */	    data.flush();	    byte hasharray[] = md.digest();	    // int minimum = Math.min(8, hasharray.length);	    // SerialBug 3: SHA computation is wrong; for loop reversed	    //for (int i = minimum; i > 0; i--) 	    for (int i = 0; i < Math.min(8, hasharray.length); i++) {		h += (long)(hasharray[i] & 255) << (i * 8);	    }	} catch (IOException ignore) {	    /* can't happen, but be deterministic anyway. */	    h = -1;	} catch (NoSuchAlgorithmException complain) {	    throw new SecurityException(complain.getMessage());	}	return h;    }    /**     * Compute the JVM signature for the class.     */    static String getSignature(Class clazz) {	String type = null;	if (clazz.isArray()) {	    Class cl = clazz;	    int dimensions = 0;	    while (cl.isArray()) {		dimensions++;		cl = cl.getComponentType();	    }	    StringBuffer sb = new StringBuffer();	    for (int i = 0; i < dimensions; i++) {		sb.append("[");	    }	    sb.append(getSignature(cl));	    type = sb.toString();	} else if (clazz.isPrimitive()) {	    if (clazz == Integer.TYPE) {		type = "I";	    } else if (clazz == Byte.TYPE) {		type = "B";	    } else if (clazz == Long.TYPE) {		type = "J";	    } else if (clazz == Float.TYPE) {		type = "F";	    } else if (clazz == Double.TYPE) {		type = "D";	    } else if (clazz == Short.TYPE) {		type = "S";	    } else if (clazz == Character.TYPE) {		type = "C";	    } else if (clazz == Boolean.TYPE) {		type = "Z";	    } else if (clazz == Void.TYPE) {		type = "V";	    }	} else {	    type = "L" + clazz.getName().replace('.', '/') + ";";	}	return type;    }    /*     * Compute the JVM method descriptor for the method.     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -