< prev index next >

src/java.base/share/classes/java/io/ObjectStreamClass.java

Print this page
rev 13121 : 8143926: ObjectStreamField constructor eagerly load ObjectStreamClass
Reviewed-by: TBD


  32 import java.lang.reflect.Constructor;
  33 import java.lang.reflect.Field;
  34 import java.lang.reflect.InvocationTargetException;
  35 import java.lang.reflect.Member;
  36 import java.lang.reflect.Method;
  37 import java.lang.reflect.Modifier;
  38 import java.lang.reflect.Proxy;
  39 import java.security.AccessController;
  40 import java.security.MessageDigest;
  41 import java.security.NoSuchAlgorithmException;
  42 import java.security.PrivilegedAction;
  43 import java.util.ArrayList;
  44 import java.util.Arrays;
  45 import java.util.Collections;
  46 import java.util.Comparator;
  47 import java.util.HashSet;
  48 import java.util.Set;
  49 import java.util.concurrent.ConcurrentHashMap;
  50 import java.util.concurrent.ConcurrentMap;
  51 import jdk.internal.misc.Unsafe;

  52 import sun.reflect.CallerSensitive;
  53 import sun.reflect.Reflection;
  54 import sun.reflect.ReflectionFactory;
  55 import sun.reflect.misc.ReflectUtil;
  56 
  57 /**
  58  * Serialization's descriptor for classes.  It contains the name and
  59  * serialVersionUID of the class.  The ObjectStreamClass for a specific class
  60  * loaded in this Java VM can be found/created using the lookup method.
  61  *
  62  * <p>The algorithm to compute the SerialVersionUID is described in
  63  * <a href="../../../platform/serialization/spec/class.html#4100">Object
  64  * Serialization Specification, Section 4.6, Stream Unique Identifiers</a>.
  65  *
  66  * @author      Mike Warres
  67  * @author      Roger Riggs
  68  * @see ObjectStreamField
  69  * @see <a href="../../../platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
  70  * @since   1.1
  71  */


1508         String s = cl.getName();
1509         int i = s.lastIndexOf('[');
1510         if (i >= 0) {
1511             s = s.substring(i + 2);
1512         }
1513         i = s.lastIndexOf('.');
1514         return (i >= 0) ? s.substring(0, i) : "";
1515     }
1516 
1517     /**
1518      * Compares class names for equality, ignoring package names.  Returns true
1519      * if class names equal, false otherwise.
1520      */
1521     private static boolean classNamesEqual(String name1, String name2) {
1522         name1 = name1.substring(name1.lastIndexOf('.') + 1);
1523         name2 = name2.substring(name2.lastIndexOf('.') + 1);
1524         return name1.equals(name2);
1525     }
1526 
1527     /**
1528      * Returns JVM type signature for given primitive.
1529      */
1530     private static String getPrimitiveSignature(Class<?> cl) {
1531         if (cl == Integer.TYPE)
1532             return "I";
1533         else if (cl == Byte.TYPE)
1534             return "B";
1535         else if (cl == Long.TYPE)
1536             return "J";
1537         else if (cl == Float.TYPE)
1538             return "F";
1539         else if (cl == Double.TYPE)
1540             return "D";
1541         else if (cl == Short.TYPE)
1542             return "S";
1543         else if (cl == Character.TYPE)
1544             return "C";
1545         else if (cl == Boolean.TYPE)
1546             return "Z";
1547         else if (cl == Void.TYPE)
1548             return "V";
1549         else
1550             throw new InternalError();
1551     }
1552 
1553     /**
1554      * Returns JVM type signature for given class.
1555      */
1556     static String getClassSignature(Class<?> cl) {
1557         if (cl.isPrimitive())
1558             return getPrimitiveSignature(cl);
1559         else
1560             return appendClassSignature(new StringBuilder(), cl).toString();
1561     }
1562 
1563     private static StringBuilder appendClassSignature(StringBuilder sbuf, Class<?> cl) {
1564        while (cl.isArray()) {
1565            sbuf.append('[');
1566            cl = cl.getComponentType();
1567        }
1568 
1569        if (cl.isPrimitive())
1570            sbuf.append(getPrimitiveSignature(cl));
1571        else
1572            sbuf.append('L').append(cl.getName().replace('.', '/')).append(';');
1573 
1574        return sbuf;
1575    }
1576 
1577     /**
1578      * Returns JVM type signature for given list of parameters and return type.
1579      */
1580     private static String getMethodSignature(Class<?>[] paramTypes,
1581                                              Class<?> retType)
1582     {
1583         StringBuilder sbuf = new StringBuilder();
1584         sbuf.append('(');
1585         for (int i = 0; i < paramTypes.length; i++) {
1586             appendClassSignature(sbuf, paramTypes[i]);
1587         }
1588         sbuf.append(')');
1589         appendClassSignature(sbuf, retType);
1590         return sbuf.toString();
1591     }
1592 
1593     /**
1594      * Convenience method for throwing an exception that is either a
1595      * RuntimeException, Error, or of some unexpected type (in which case it is
1596      * wrapped inside an IOException).
1597      */
1598     private static void throwMiscException(Throwable th) throws IOException {
1599         if (th instanceof RuntimeException) {
1600             throw (RuntimeException) th;
1601         } else if (th instanceof Error) {
1602             throw (Error) th;
1603         } else {
1604             IOException ex = new IOException("unexpected exception type");
1605             ex.initCause(th);
1606             throw ex;
1607         }
1608     }
1609 
1610     /**
1611      * Returns ObjectStreamField array describing the serializable fields of
1612      * the given class.  Serializable fields backed by an actual field of the
1613      * class are represented by ObjectStreamFields with corresponding non-null


1881 
1882     /**
1883      * Returns true if the given class defines a static initializer method,
1884      * false otherwise.
1885      */
1886     private static native boolean hasStaticInitializer(Class<?> cl);
1887 
1888     /**
1889      * Class for computing and caching field/constructor/method signatures
1890      * during serialVersionUID calculation.
1891      */
1892     private static class MemberSignature {
1893 
1894         public final Member member;
1895         public final String name;
1896         public final String signature;
1897 
1898         public MemberSignature(Field field) {
1899             member = field;
1900             name = field.getName();
1901             signature = getClassSignature(field.getType());
1902         }
1903 
1904         public MemberSignature(Constructor<?> cons) {
1905             member = cons;
1906             name = cons.getName();
1907             signature = getMethodSignature(
1908                 cons.getParameterTypes(), Void.TYPE);
1909         }
1910 
1911         public MemberSignature(Method meth) {
1912             member = meth;
1913             name = meth.getName();
1914             signature = getMethodSignature(
1915                 meth.getParameterTypes(), meth.getReturnType());
1916         }
1917     }
1918 
1919     /**
1920      * Class for setting and retrieving serializable field values in batch.
1921      */
1922     // REMIND: dynamically generate these?
1923     private static class FieldReflector {
1924 
1925         /** handle for performing unsafe operations */
1926         private static final Unsafe unsafe = Unsafe.getUnsafe();
1927 
1928         /** fields to operate on */
1929         private final ObjectStreamField[] fields;
1930         /** number of primitive fields */
1931         private final int numPrimFields;
1932         /** unsafe field keys for reading fields - may contain dupes */
1933         private final long[] readKeys;
1934         /** unsafe fields keys for writing fields - no dupes */
1935         private final long[] writeKeys;




  32 import java.lang.reflect.Constructor;
  33 import java.lang.reflect.Field;
  34 import java.lang.reflect.InvocationTargetException;
  35 import java.lang.reflect.Member;
  36 import java.lang.reflect.Method;
  37 import java.lang.reflect.Modifier;
  38 import java.lang.reflect.Proxy;
  39 import java.security.AccessController;
  40 import java.security.MessageDigest;
  41 import java.security.NoSuchAlgorithmException;
  42 import java.security.PrivilegedAction;
  43 import java.util.ArrayList;
  44 import java.util.Arrays;
  45 import java.util.Collections;
  46 import java.util.Comparator;
  47 import java.util.HashSet;
  48 import java.util.Set;
  49 import java.util.concurrent.ConcurrentHashMap;
  50 import java.util.concurrent.ConcurrentMap;
  51 import jdk.internal.misc.Unsafe;
  52 import sun.invoke.util.BytecodeDescriptor;
  53 import sun.reflect.CallerSensitive;
  54 import sun.reflect.Reflection;
  55 import sun.reflect.ReflectionFactory;
  56 import sun.reflect.misc.ReflectUtil;
  57 
  58 /**
  59  * Serialization's descriptor for classes.  It contains the name and
  60  * serialVersionUID of the class.  The ObjectStreamClass for a specific class
  61  * loaded in this Java VM can be found/created using the lookup method.
  62  *
  63  * <p>The algorithm to compute the SerialVersionUID is described in
  64  * <a href="../../../platform/serialization/spec/class.html#4100">Object
  65  * Serialization Specification, Section 4.6, Stream Unique Identifiers</a>.
  66  *
  67  * @author      Mike Warres
  68  * @author      Roger Riggs
  69  * @see ObjectStreamField
  70  * @see <a href="../../../platform/serialization/spec/class.html">Object Serialization Specification, Section 4, Class Descriptors</a>
  71  * @since   1.1
  72  */


1509         String s = cl.getName();
1510         int i = s.lastIndexOf('[');
1511         if (i >= 0) {
1512             s = s.substring(i + 2);
1513         }
1514         i = s.lastIndexOf('.');
1515         return (i >= 0) ? s.substring(0, i) : "";
1516     }
1517 
1518     /**
1519      * Compares class names for equality, ignoring package names.  Returns true
1520      * if class names equal, false otherwise.
1521      */
1522     private static boolean classNamesEqual(String name1, String name2) {
1523         name1 = name1.substring(name1.lastIndexOf('.') + 1);
1524         name2 = name2.substring(name2.lastIndexOf('.') + 1);
1525         return name1.equals(name2);
1526     }
1527 
1528     /**


































































1529      * Convenience method for throwing an exception that is either a
1530      * RuntimeException, Error, or of some unexpected type (in which case it is
1531      * wrapped inside an IOException).
1532      */
1533     private static void throwMiscException(Throwable th) throws IOException {
1534         if (th instanceof RuntimeException) {
1535             throw (RuntimeException) th;
1536         } else if (th instanceof Error) {
1537             throw (Error) th;
1538         } else {
1539             IOException ex = new IOException("unexpected exception type");
1540             ex.initCause(th);
1541             throw ex;
1542         }
1543     }
1544 
1545     /**
1546      * Returns ObjectStreamField array describing the serializable fields of
1547      * the given class.  Serializable fields backed by an actual field of the
1548      * class are represented by ObjectStreamFields with corresponding non-null


1816 
1817     /**
1818      * Returns true if the given class defines a static initializer method,
1819      * false otherwise.
1820      */
1821     private static native boolean hasStaticInitializer(Class<?> cl);
1822 
1823     /**
1824      * Class for computing and caching field/constructor/method signatures
1825      * during serialVersionUID calculation.
1826      */
1827     private static class MemberSignature {
1828 
1829         public final Member member;
1830         public final String name;
1831         public final String signature;
1832 
1833         public MemberSignature(Field field) {
1834             member = field;
1835             name = field.getName();
1836             signature = BytecodeDescriptor.unparse(field.getType());
1837         }
1838 
1839         public MemberSignature(Constructor<?> cons) {
1840             member = cons;
1841             name = cons.getName();
1842             signature = BytecodeDescriptor.unparseMethod(
1843                     Void.TYPE, cons.getParameterTypes());
1844         }
1845 
1846         public MemberSignature(Method meth) {
1847             member = meth;
1848             name = meth.getName();
1849             signature = BytecodeDescriptor.unparseMethod(
1850                 meth.getReturnType(), meth.getParameterTypes());
1851         }
1852     }
1853 
1854     /**
1855      * Class for setting and retrieving serializable field values in batch.
1856      */
1857     // REMIND: dynamically generate these?
1858     private static class FieldReflector {
1859 
1860         /** handle for performing unsafe operations */
1861         private static final Unsafe unsafe = Unsafe.getUnsafe();
1862 
1863         /** fields to operate on */
1864         private final ObjectStreamField[] fields;
1865         /** number of primitive fields */
1866         private final int numPrimFields;
1867         /** unsafe field keys for reading fields - may contain dupes */
1868         private final long[] readKeys;
1869         /** unsafe fields keys for writing fields - no dupes */
1870         private final long[] writeKeys;


< prev index next >