< prev index next >

src/java.base/share/classes/java/lang/Class.java

Print this page
rev 49906 : 8187123: (reflect) Class#getCanonicalName and Class#getSimpleName is a part of performance issue
Reviewed-by: psandoz


1507                 enclosingCandidate.checkPackageAccess(sm,
1508                     ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
1509             }
1510         }
1511         return enclosingCandidate;
1512     }
1513 
1514     /**
1515      * Returns the simple name of the underlying class as given in the
1516      * source code. Returns an empty string if the underlying class is
1517      * anonymous.
1518      *
1519      * <p>The simple name of an array is the simple name of the
1520      * component type with "[]" appended.  In particular the simple
1521      * name of an array whose component type is anonymous is "[]".
1522      *
1523      * @return the simple name of the underlying class
1524      * @since 1.5
1525      */
1526     public String getSimpleName() {
1527         if (isArray())
1528             return getComponentType().getSimpleName()+"[]";





1529 




1530         String simpleName = getSimpleBinaryName();
1531         if (simpleName == null) { // top level class
1532             simpleName = getName();
1533             return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name
1534         }
1535         return simpleName;
1536     }
1537 
1538     /**
1539      * Return an informative string for the name of this type.
1540      *
1541      * @return an informative string for the name of this type
1542      * @since 1.8
1543      */
1544     public String getTypeName() {









1545         if (isArray()) {
1546             try {
1547                 Class<?> cl = this;
1548                 int dimensions = 0;
1549                 while (cl.isArray()) {
1550                     dimensions++;
1551                     cl = cl.getComponentType();
1552                 }
1553                 StringBuilder sb = new StringBuilder();
1554                 sb.append(cl.getName());
1555                 for (int i = 0; i < dimensions; i++) {
1556                     sb.append("[]");
1557                 }
1558                 return sb.toString();
1559             } catch (Throwable e) { /*FALLTHRU*/ }
1560         }
1561         return getName();
1562     }
1563 
1564     /**
1565      * Returns the canonical name of the underlying class as
1566      * defined by the Java Language Specification.  Returns null if
1567      * the underlying class does not have a canonical name (i.e., if
1568      * it is a local or anonymous class or an array whose component
1569      * type does not have a canonical name).
1570      * @return the canonical name of the underlying class if it exists, and
1571      * {@code null} otherwise.
1572      * @since 1.5
1573      */
1574     public String getCanonicalName() {









1575         if (isArray()) {
1576             String canonicalName = getComponentType().getCanonicalName();
1577             if (canonicalName != null)
1578                 return canonicalName + "[]";
1579             else
1580                 return null;
1581         }
1582         if (isLocalOrAnonymousClass())
1583             return null;
1584         Class<?> enclosingClass = getEnclosingClass();
1585         if (enclosingClass == null) { // top level class
1586             return getName();
1587         } else {
1588             String enclosingName = enclosingClass.getCanonicalName();
1589             if (enclosingName == null)
1590                 return null;
1591             return enclosingName + "." + getSimpleName();
1592         }
1593     }
1594 
1595     /**
1596      * Returns {@code true} if and only if the underlying class
1597      * is an anonymous class.
1598      *
1599      * @return {@code true} if and only if this class is an anonymous class.
1600      * @since 1.5
1601      */
1602     public boolean isAnonymousClass() {
1603         return !isArray() && isLocalOrAnonymousClass() &&
1604                 getSimpleBinaryName0() == null;
1605     }
1606 
1607     /**
1608      * Returns {@code true} if and only if the underlying class
1609      * is a local class.
1610      *


2890             return unsafe.compareAndSetObject(clazz, annotationDataOffset, oldData, newData);
2891         }
2892     }
2893 
2894     /**
2895      * Reflection support.
2896      */
2897 
2898     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
2899     private static class ReflectionData<T> {
2900         volatile Field[] declaredFields;
2901         volatile Field[] publicFields;
2902         volatile Method[] declaredMethods;
2903         volatile Method[] publicMethods;
2904         volatile Constructor<T>[] declaredConstructors;
2905         volatile Constructor<T>[] publicConstructors;
2906         // Intermediate results for getFields and getMethods
2907         volatile Field[] declaredPublicFields;
2908         volatile Method[] declaredPublicMethods;
2909         volatile Class<?>[] interfaces;






2910 
2911         // Value of classRedefinedCount when we created this ReflectionData instance
2912         final int redefinedCount;
2913 
2914         ReflectionData(int redefinedCount) {
2915             this.redefinedCount = redefinedCount;
2916         }
2917     }
2918 
2919     private transient volatile SoftReference<ReflectionData<T>> reflectionData;
2920 
2921     // Incremented by the VM on each call to JVM TI RedefineClasses()
2922     // that redefines this class or a superclass.
2923     private transient volatile int classRedefinedCount;
2924 
2925     // Lazily create and cache ReflectionData
2926     private ReflectionData<T> reflectionData() {
2927         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2928         int classRedefinedCount = this.classRedefinedCount;
2929         ReflectionData<T> rd;




1507                 enclosingCandidate.checkPackageAccess(sm,
1508                     ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
1509             }
1510         }
1511         return enclosingCandidate;
1512     }
1513 
1514     /**
1515      * Returns the simple name of the underlying class as given in the
1516      * source code. Returns an empty string if the underlying class is
1517      * anonymous.
1518      *
1519      * <p>The simple name of an array is the simple name of the
1520      * component type with "[]" appended.  In particular the simple
1521      * name of an array whose component type is anonymous is "[]".
1522      *
1523      * @return the simple name of the underlying class
1524      * @since 1.5
1525      */
1526     public String getSimpleName() {
1527         ReflectionData<T> rd = reflectionData();
1528         String simpleName = rd.simpleName;
1529         if (simpleName == null) {
1530             rd.simpleName = simpleName = getSimpleName0();
1531         }
1532         return simpleName;
1533     }
1534 
1535     private String getSimpleName0() {
1536         if (isArray()) {
1537             return getComponentType().getSimpleName() + "[]";
1538         }
1539         String simpleName = getSimpleBinaryName();
1540         if (simpleName == null) { // top level class
1541             simpleName = getName();
1542             simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1); // strip the package name
1543         }
1544         return simpleName;
1545     }
1546 
1547     /**
1548      * Return an informative string for the name of this type.
1549      *
1550      * @return an informative string for the name of this type
1551      * @since 1.8
1552      */
1553     public String getTypeName() {
1554         ReflectionData<T> rd = reflectionData();
1555         String typeName = rd.typeName;
1556         if (typeName == null) {
1557             rd.typeName = typeName = getTypeName0();
1558         }
1559         return typeName;
1560     }
1561 
1562     private String getTypeName0() {
1563         if (isArray()) {
1564             try {
1565                 Class<?> cl = this;
1566                 int dimensions = 0;
1567                 while (cl.isArray()) {
1568                     dimensions++;
1569                     cl = cl.getComponentType();
1570                 }
1571                 StringBuilder sb = new StringBuilder();
1572                 sb.append(cl.getName());
1573                 for (int i = 0; i < dimensions; i++) {
1574                     sb.append("[]");
1575                 }
1576                 return sb.toString();
1577             } catch (Throwable e) { /*FALLTHRU*/ }
1578         }
1579         return getName();
1580     }
1581 
1582     /**
1583      * Returns the canonical name of the underlying class as
1584      * defined by the Java Language Specification.  Returns null if
1585      * the underlying class does not have a canonical name (i.e., if
1586      * it is a local or anonymous class or an array whose component
1587      * type does not have a canonical name).
1588      * @return the canonical name of the underlying class if it exists, and
1589      * {@code null} otherwise.
1590      * @since 1.5
1591      */
1592     public String getCanonicalName() {
1593         ReflectionData<T> rd = reflectionData();
1594         String canonicalName = rd.canonicalName;
1595         if (canonicalName == null) {
1596             rd.canonicalName = canonicalName = getCanonicalName0();
1597         }
1598         return canonicalName == ReflectionData.NULL_SENTINEL? null : canonicalName;
1599     }
1600 
1601     private String getCanonicalName0() {
1602         if (isArray()) {
1603             String canonicalName = getComponentType().getCanonicalName();
1604             if (canonicalName != null)
1605                 return canonicalName + "[]";
1606             else
1607                 return ReflectionData.NULL_SENTINEL;
1608         }
1609         if (isLocalOrAnonymousClass())
1610             return ReflectionData.NULL_SENTINEL;
1611         Class<?> enclosingClass = getEnclosingClass();
1612         if (enclosingClass == null) { // top level class
1613             return getName();
1614         } else {
1615             String enclosingName = enclosingClass.getCanonicalName();
1616             if (enclosingName == null)
1617                 return ReflectionData.NULL_SENTINEL;
1618             return enclosingName + "." + getSimpleName();
1619         }
1620     }
1621 
1622     /**
1623      * Returns {@code true} if and only if the underlying class
1624      * is an anonymous class.
1625      *
1626      * @return {@code true} if and only if this class is an anonymous class.
1627      * @since 1.5
1628      */
1629     public boolean isAnonymousClass() {
1630         return !isArray() && isLocalOrAnonymousClass() &&
1631                 getSimpleBinaryName0() == null;
1632     }
1633 
1634     /**
1635      * Returns {@code true} if and only if the underlying class
1636      * is a local class.
1637      *


2917             return unsafe.compareAndSetObject(clazz, annotationDataOffset, oldData, newData);
2918         }
2919     }
2920 
2921     /**
2922      * Reflection support.
2923      */
2924 
2925     // reflection data that might get invalidated when JVM TI RedefineClasses() is called
2926     private static class ReflectionData<T> {
2927         volatile Field[] declaredFields;
2928         volatile Field[] publicFields;
2929         volatile Method[] declaredMethods;
2930         volatile Method[] publicMethods;
2931         volatile Constructor<T>[] declaredConstructors;
2932         volatile Constructor<T>[] publicConstructors;
2933         // Intermediate results for getFields and getMethods
2934         volatile Field[] declaredPublicFields;
2935         volatile Method[] declaredPublicMethods;
2936         volatile Class<?>[] interfaces;
2937 
2938         // Cached names
2939         volatile String simpleName;
2940         volatile String canonicalName;
2941         volatile String typeName;
2942         static final String NULL_SENTINEL = "$$$nil$$$";
2943 
2944         // Value of classRedefinedCount when we created this ReflectionData instance
2945         final int redefinedCount;
2946 
2947         ReflectionData(int redefinedCount) {
2948             this.redefinedCount = redefinedCount;
2949         }
2950     }
2951 
2952     private transient volatile SoftReference<ReflectionData<T>> reflectionData;
2953 
2954     // Incremented by the VM on each call to JVM TI RedefineClasses()
2955     // that redefines this class or a superclass.
2956     private transient volatile int classRedefinedCount;
2957 
2958     // Lazily create and cache ReflectionData
2959     private ReflectionData<T> reflectionData() {
2960         SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
2961         int classRedefinedCount = this.classRedefinedCount;
2962         ReflectionData<T> rd;


< prev index next >