# HG changeset patch # User redestad # Date 1525091917 -7200 # Mon Apr 30 14:38:37 2018 +0200 # Node ID 65dca081564698c168c2d716f061f026d91814ff # Parent b708a1e34fcc3f884206cd3706ad5fbfe503ce10 8187123: (reflect) Class#getCanonicalName and Class#getSimpleName is a part of performance issue Reviewed-by: psandoz diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -1524,13 +1524,22 @@ * @since 1.5 */ public String getSimpleName() { - if (isArray()) - return getComponentType().getSimpleName()+"[]"; - + ReflectionData rd = reflectionData(); + String simpleName = rd.simpleName; + if (simpleName == null) { + rd.simpleName = simpleName = getSimpleName0(); + } + return simpleName; + } + + private String getSimpleName0() { + if (isArray()) { + return getComponentType().getSimpleName() + "[]"; + } String simpleName = getSimpleBinaryName(); if (simpleName == null) { // top level class simpleName = getName(); - return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name + simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1); // strip the package name } return simpleName; } @@ -1546,10 +1555,10 @@ try { Class cl = this; int dimensions = 0; - while (cl.isArray()) { + do { dimensions++; cl = cl.getComponentType(); - } + } while (cl.isArray()); StringBuilder sb = new StringBuilder(); sb.append(cl.getName()); for (int i = 0; i < dimensions; i++) { @@ -1572,22 +1581,31 @@ * @since 1.5 */ public String getCanonicalName() { + ReflectionData rd = reflectionData(); + String canonicalName = rd.canonicalName; + if (canonicalName == null) { + rd.canonicalName = canonicalName = getCanonicalName0(); + } + return canonicalName == ReflectionData.NULL_SENTINEL? null : canonicalName; + } + + private String getCanonicalName0() { if (isArray()) { String canonicalName = getComponentType().getCanonicalName(); if (canonicalName != null) return canonicalName + "[]"; else - return null; + return ReflectionData.NULL_SENTINEL; } if (isLocalOrAnonymousClass()) - return null; + return ReflectionData.NULL_SENTINEL; Class enclosingClass = getEnclosingClass(); if (enclosingClass == null) { // top level class return getName(); } else { String enclosingName = enclosingClass.getCanonicalName(); if (enclosingName == null) - return null; + return ReflectionData.NULL_SENTINEL; return enclosingName + "." + getSimpleName(); } } @@ -2908,6 +2926,11 @@ volatile Method[] declaredPublicMethods; volatile Class[] interfaces; + // Cached names + volatile String simpleName; + volatile String canonicalName; + static final String NULL_SENTINEL = new String(); + // Value of classRedefinedCount when we created this ReflectionData instance final int redefinedCount;