--- old/src/java.base/share/classes/java/io/ObjectStreamField.java 2017-07-15 14:01:55.772732418 +0200 +++ new/src/java.base/share/classes/java/io/ObjectStreamField.java 2017-07-15 14:01:55.695733092 +0200 @@ -91,7 +91,7 @@ this.name = name; this.type = type; this.unshared = unshared; - signature = getClassSignature(type).intern(); + signature = null; // will be lazily obtained from type field = null; } @@ -124,58 +124,6 @@ } /** - * Returns JVM type signature for given primitive. - */ - private static String getPrimitiveSignature(Class cl) { - if (cl == Integer.TYPE) - return "I"; - else if (cl == Byte.TYPE) - return "B"; - else if (cl == Long.TYPE) - return "J"; - else if (cl == Float.TYPE) - return "F"; - else if (cl == Double.TYPE) - return "D"; - else if (cl == Short.TYPE) - return "S"; - else if (cl == Character.TYPE) - return "C"; - else if (cl == Boolean.TYPE) - return "Z"; - else if (cl == Void.TYPE) - return "V"; - else - throw new InternalError(); - } - - /** - * Returns JVM type signature for given class. - */ - static String getClassSignature(Class cl) { - if (cl.isPrimitive()) { - return getPrimitiveSignature(cl); - } else { - return appendClassSignature(new StringBuilder(), cl).toString(); - } - } - - static StringBuilder appendClassSignature(StringBuilder sbuf, Class cl) { - while (cl.isArray()) { - sbuf.append('['); - cl = cl.getComponentType(); - } - - if (cl.isPrimitive()) { - sbuf.append(getPrimitiveSignature(cl)); - } else { - sbuf.append('L').append(cl.getName().replace('.', '/')).append(';'); - } - - return sbuf; - } - - /** * Creates an ObjectStreamField representing the given field with the * specified unshared setting. For compatibility with the behavior of * earlier serialization implementations, a "showType" parameter is @@ -188,8 +136,13 @@ this.unshared = unshared; name = field.getName(); Class ftype = field.getType(); - type = (showType || ftype.isPrimitive()) ? ftype : Object.class; - signature = getClassSignature(ftype).intern(); + if (showType || ftype.isPrimitive()) { + type = ftype; + signature = null; // will be lazily obtained from type + } else { + type = Object.class; + signature = ftype.getJvmTypeSignature(); + } } /** @@ -242,7 +195,7 @@ */ // REMIND: deprecate? public char getTypeCode() { - return signature.charAt(0); + return getSignature().charAt(0); } /** @@ -252,7 +205,7 @@ */ // REMIND: deprecate? public String getTypeString() { - return isPrimitive() ? null : signature; + return isPrimitive() ? null : getSignature(); } /** @@ -284,7 +237,7 @@ */ // REMIND: deprecate? public boolean isPrimitive() { - char tcode = signature.charAt(0); + char tcode = getSignature().charAt(0); return ((tcode != 'L') && (tcode != '[')); } @@ -320,7 +273,7 @@ * Return a string that describes this field. */ public String toString() { - return signature + ' ' + name; + return getSignature() + ' ' + name; } /** @@ -336,6 +289,6 @@ * that signature strings are returned for primitive fields as well). */ String getSignature() { - return signature; + return signature == null ? type.getJvmTypeSignature() : signature; } } --- old/src/java.base/share/classes/java/lang/Class.java 2017-07-15 14:01:56.073729786 +0200 +++ new/src/java.base/share/classes/java/lang/Class.java 2017-07-15 14:01:55.998730442 +0200 @@ -773,6 +773,82 @@ private transient String name; private native String getName0(); + // JVM type signature, calculated lazily, interned and cached + private transient String signature; + + /** + * Returns a type signature for a Java Virtual Machine type represented by this + * Class object. + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
JVM Type Signature Java Type
Vvoid
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
Lfully-qualified-class ;fully-qualified-class
[ typetype[]
+ * + * @return Java Virtual Machine type signature represented by this Class, interned. + * @since 10 + */ + public String getJvmTypeSignature() { + String sig = signature; + if (sig == null) { + signature = sig = isPrimitive() + ? getPrimitiveSignature(this) // already interned + : appendClassSignature(new StringBuilder(), this) + .toString().intern(); + } + return sig; + } + + // Returns JVM type signature for given primitive. + private static String getPrimitiveSignature(Class cl) { + if (cl == Integer.TYPE) + return "I"; + else if (cl == Byte.TYPE) + return "B"; + else if (cl == Long.TYPE) + return "J"; + else if (cl == Float.TYPE) + return "F"; + else if (cl == Double.TYPE) + return "D"; + else if (cl == Short.TYPE) + return "S"; + else if (cl == Character.TYPE) + return "C"; + else if (cl == Boolean.TYPE) + return "Z"; + else if (cl == Void.TYPE) + return "V"; + else + throw new InternalError(); + } + + // appends JVM type signature for given non-primitive + private static StringBuilder appendClassSignature(StringBuilder sbuf, Class cl) { + while (cl.isArray()) { + sbuf.append('['); + cl = cl.getComponentType(); + } + + if (cl.isPrimitive()) { + sbuf.append(getPrimitiveSignature(cl)); + } else { + sbuf.append('L').append(cl.getName().replace('.', '/')).append(';'); + } + + return sbuf; + } + /** * Returns the class loader for the class. Some implementations may use * null to represent the bootstrap class loader. This method will return