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

📄 objectstreamclassutil_1_3.java

📁 JAVA 所有包
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * @(#)ObjectStreamClassUtil_1_3.java	1.8 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.corba.se.impl.orbutil;// for computing the structural UIDimport 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.io.DataOutputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Arrays;import java.util.Comparator;import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.lang.reflect.Array;import java.lang.reflect.Member;import java.lang.reflect.Method;import java.lang.reflect.Constructor;import com.sun.corba.se.impl.io.ObjectStreamClass;public final class ObjectStreamClassUtil_1_3 {    // maintained here for backward compatability with JDK 1.3, where    // writeObject method was not being checked at all, so there is    // no need to lookup the ObjectStreamClass    public static long computeSerialVersionUID(final Class cl) {		long csuid = ObjectStreamClass.getSerialVersionUID(cl);	if (csuid == 0)	    return csuid; // for non-serializable/proxy classes	csuid = (ObjectStreamClassUtil_1_3.getSerialVersion(csuid, cl).longValue());	return csuid;    }	    // to maintain same suid as the JDK 1.3, we pick    // up suid only for classes with private,static,final    // declarations, and compute it for all others    private static Long getSerialVersion(final long csuid, final Class cl)    {        return (Long) AccessController.doPrivileged(new PrivilegedAction() {          public Object run() {	    long suid;	    try {                final Field f = cl.getDeclaredField("serialVersionUID");	        int mods = f.getModifiers();	        if (Modifier.isStatic(mods) &&                     Modifier.isFinal(mods) && Modifier.isPrivate(mods)) {	            suid = csuid;	         } else {		    suid = _computeSerialVersionUID(cl);	         }	      } catch (NoSuchFieldException ex) {	          suid = _computeSerialVersionUID(cl);              //} catch (IllegalAccessException ex) {              //     suid = _computeSerialVersionUID(cl);              }	      return new Long(suid);	   }	});    }    public static long computeStructuralUID(boolean hasWriteObject, 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);	    //In the old case, for the caller class, the write Method wasn't considered	    // for rep-id calculations correctly, but for parent classes it was taken	    // into account.  That is the reason there is the klude of getting the write	    // Object method in there	    // Get SUID of parent	    Class parent = cl.getSuperclass();	    if ((parent != null) && (parent != java.lang.Object.class)) {	        boolean hasWriteObjectFlag = false;	        Class [] args = {java.io.ObjectOutputStream.class};                Method hasWriteObjectMethod = ObjectStreamClassUtil_1_3.getDeclaredMethod(parent, "writeObject", args,	               Modifier.PRIVATE, Modifier.STATIC);	        if (hasWriteObjectMethod != null)	            hasWriteObjectFlag = true; 		data.writeLong(ObjectStreamClassUtil_1_3.computeStructuralUID(hasWriteObjectFlag, parent));	    }	    if (hasWriteObject)	        data.writeInt(2);	    else	        data.writeInt(1);	    /* Sort the field names to get a deterministic order */	    Field[] field = ObjectStreamClassUtil_1_3.getDeclaredFields(cl);	    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				 * transient or static.				 */		int m = f.getModifiers();		if (Modifier.isTransient(m) || Modifier.isStatic(m))		    continue;						data.writeUTF(f.getName());		data.writeUTF(getSignature(f.getType()));	    }				    /* 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);	    for (int i = minimum; i > 0; 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 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()));	    }	    // need to find the java replacement for hasStaticInitializer	    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();

⌨️ 快捷键说明

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