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;
|