< prev index next >

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

Print this page
rev 49922 : 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         if (isArray()) {
1555             try {
1556                 Class<?> cl = this;
1557                 int dimensions = 0;
1558                 do {
1559                     dimensions++;
1560                     cl = cl.getComponentType();
1561                 } while (cl.isArray());
1562                 StringBuilder sb = new StringBuilder();
1563                 sb.append(cl.getName());
1564                 for (int i = 0; i < dimensions; i++) {
1565                     sb.append("[]");
1566                 }
1567                 return sb.toString();
1568             } catch (Throwable e) { /*FALLTHRU*/ }
1569         }
1570         return getName();
1571     }
1572 
1573     /**
1574      * Returns the canonical name of the underlying class as
1575      * defined by the Java Language Specification.  Returns null if
1576      * the underlying class does not have a canonical name (i.e., if
1577      * it is a local or anonymous class or an array whose component
1578      * type does not have a canonical name).
1579      * @return the canonical name of the underlying class if it exists, and
1580      * {@code null} otherwise.
1581      * @since 1.5
1582      */
1583     public String getCanonicalName() {
1584         ReflectionData<T> rd = reflectionData();
1585         String canonicalName = rd.canonicalName;
1586         if (canonicalName == null) {
1587             rd.canonicalName = canonicalName = getCanonicalName0();
1588         }
1589         return canonicalName == ReflectionData.NULL_SENTINEL? null : canonicalName;
1590     }
1591 
1592     private String getCanonicalName0() {
1593         if (isArray()) {
1594             String canonicalName = getComponentType().getCanonicalName();
1595             if (canonicalName != null)
1596                 return canonicalName + "[]";
1597             else
1598                 return ReflectionData.NULL_SENTINEL;
1599         }
1600         if (isLocalOrAnonymousClass())
1601             return ReflectionData.NULL_SENTINEL;
1602         Class<?> enclosingClass = getEnclosingClass();
1603         if (enclosingClass == null) { // top level class
1604             return getName();
1605         } else {
1606             String enclosingName = enclosingClass.getCanonicalName();
1607             if (enclosingName == null)
1608                 return ReflectionData.NULL_SENTINEL;
1609             return enclosingName + "." + getSimpleName();
1610         }
1611     }
1612 
1613     /**
1614      * Returns {@code true} if and only if the underlying class
1615      * is an anonymous class.
1616      *
1617      * @return {@code true} if and only if this class is an anonymous class.
1618      * @since 1.5
1619      */
1620     public boolean isAnonymousClass() {
1621         return !isArray() && isLocalOrAnonymousClass() &&
1622                 getSimpleBinaryName0() == null;
1623     }
1624 
1625     /**
1626      * Returns {@code true} if and only if the underlying class
1627      * is a local class.
1628      *


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


< prev index next >