8187123: (reflect) Class#getCanonicalName and Class#getSimpleName is a part of performance issue

Reviewed-by: psandoz, dholmes, mchung
This commit is contained in:
Claes Redestad 2018-05-04 09:29:14 +02:00
parent d9b3c3203e
commit d1cf230fc1

View File

@ -1524,13 +1524,22 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.5
*/
public String getSimpleName() {
if (isArray())
return getComponentType().getSimpleName()+"[]";
ReflectionData<T> 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 @@ public final class Class<T> implements java.io.Serializable,
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 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.5
*/
public String getCanonicalName() {
ReflectionData<T> 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();
}
}
@ -2895,7 +2913,8 @@ public final class Class<T> implements java.io.Serializable,
* Reflection support.
*/
// reflection data that might get invalidated when JVM TI RedefineClasses() is called
// Reflection data caches various derived names and reflective members. Cached
// values may be invalidated when JVM TI RedefineClasses() is called
private static class ReflectionData<T> {
volatile Field[] declaredFields;
volatile Field[] publicFields;
@ -2908,6 +2927,11 @@ public final class Class<T> implements java.io.Serializable,
volatile Method[] declaredPublicMethods;
volatile Class<?>[] interfaces;
// Cached names
String simpleName;
String canonicalName;
static final String NULL_SENTINEL = new String();
// Value of classRedefinedCount when we created this ReflectionData instance
final int redefinedCount;