1255
1256 if (matches) { // finally, check return type
1257 if (m.getReturnType().equals(returnType) )
1258 return m;
1259 }
1260 }
1261 }
1262 }
1263
1264 throw new InternalError("Enclosing method not found");
1265 }
1266 }
1267
1268 private native Object[] getEnclosingMethod0();
1269
1270 private EnclosingMethodInfo getEnclosingMethodInfo() {
1271 Object[] enclosingInfo = getEnclosingMethod0();
1272 if (enclosingInfo == null)
1273 return null;
1274 else {
1275 return new EnclosingMethodInfo(enclosingInfo);
1276 }
1277 }
1278
1279 private static final class EnclosingMethodInfo {
1280 private Class<?> enclosingClass;
1281 private String name;
1282 private String descriptor;
1283
1284 private EnclosingMethodInfo(Object[] enclosingInfo) {
1285 if (enclosingInfo.length != 3)
1286 throw new InternalError("Malformed enclosing method information");
1287 try {
1288 // The array is expected to have three elements:
1289
1290 // the immediately enclosing class
1291 enclosingClass = (Class<?>) enclosingInfo[0];
1292 assert(enclosingClass != null);
1293
1294 // the immediately enclosing method or constructor's
1295 // name (can be null).
1296 name = (String) enclosingInfo[1];
1297
1298 // the immediately enclosing method or constructor's
1299 // descriptor (null iff name is).
1300 descriptor = (String) enclosingInfo[2];
1301 assert((name != null && descriptor != null) || name == descriptor);
1302 } catch (ClassCastException cce) {
1303 throw new InternalError("Invalid type in enclosing method information", cce);
1304 }
1305 }
1306
1307 boolean isPartial() {
1308 return enclosingClass == null || name == null || descriptor == null;
1309 }
1310
1311 boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
1312
1313 boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
1314
1315 Class<?> getEnclosingClass() { return enclosingClass; }
1316
1317 String getName() { return name; }
1318
1319 String getDescriptor() { return descriptor; }
1320
1321 }
1322
1323 private static Class<?> toClass(Type o) {
1324 if (o instanceof GenericArrayType)
1325 return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
1326 0)
1464 * @since 1.5
1465 */
1466 @CallerSensitive
1467 public Class<?> getEnclosingClass() throws SecurityException {
1468 // There are five kinds of classes (or interfaces):
1469 // a) Top level classes
1470 // b) Nested classes (static member classes)
1471 // c) Inner classes (non-static member classes)
1472 // d) Local classes (named classes declared within a method)
1473 // e) Anonymous classes
1474
1475
1476 // JVM Spec 4.7.7: A class must have an EnclosingMethod
1477 // attribute if and only if it is a local class or an
1478 // anonymous class.
1479 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1480 Class<?> enclosingCandidate;
1481
1482 if (enclosingInfo == null) {
1483 // This is a top level or a nested class or an inner class (a, b, or c)
1484 enclosingCandidate = getDeclaringClass();
1485 } else {
1486 Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1487 // This is a local class or an anonymous class (d or e)
1488 if (enclosingClass == this || enclosingClass == null)
1489 throw new InternalError("Malformed enclosing method information");
1490 else
1491 enclosingCandidate = enclosingClass;
1492 }
1493
1494 if (enclosingCandidate != null)
1495 enclosingCandidate.checkPackageAccess(
1496 ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
1497 return enclosingCandidate;
1498 }
1499
1500 /**
1501 * Returns the simple name of the underlying class as given in the
1502 * source code. Returns an empty string if the underlying class is
1503 * anonymous.
1504 *
1531 if (isArray()) {
1532 try {
1533 Class<?> cl = this;
1534 int dimensions = 0;
1535 while (cl.isArray()) {
1536 dimensions++;
1537 cl = cl.getComponentType();
1538 }
1539 StringBuilder sb = new StringBuilder();
1540 sb.append(cl.getName());
1541 for (int i = 0; i < dimensions; i++) {
1542 sb.append("[]");
1543 }
1544 return sb.toString();
1545 } catch (Throwable e) { /*FALLTHRU*/ }
1546 }
1547 return getName();
1548 }
1549
1550 /**
1551 * Character.isDigit answers {@code true} to some non-ascii
1552 * digits. This one does not.
1553 */
1554 private static boolean isAsciiDigit(char c) {
1555 return '0' <= c && c <= '9';
1556 }
1557
1558 /**
1559 * Returns the canonical name of the underlying class as
1560 * defined by the Java Language Specification. Returns null if
1561 * the underlying class does not have a canonical name (i.e., if
1562 * it is a local or anonymous class or an array whose component
1563 * type does not have a canonical name).
1564 * @return the canonical name of the underlying class if it exists, and
1565 * {@code null} otherwise.
1566 * @since 1.5
1567 */
1568 public String getCanonicalName() {
1569 if (isArray()) {
1570 String canonicalName = getComponentType().getCanonicalName();
1571 if (canonicalName != null)
1572 return canonicalName + "[]";
1573 else
1574 return null;
1575 }
1576 if (isLocalOrAnonymousClass())
1577 return null;
1578 Class<?> enclosingClass = getEnclosingClass();
1579 if (enclosingClass == null) { // top level class
1580 return getName();
1581 } else {
1582 String enclosingName = enclosingClass.getCanonicalName();
1583 if (enclosingName == null)
1584 return null;
1585 return enclosingName + "." + getSimpleName();
1586 }
1587 }
1588
1589 /**
1590 * Returns {@code true} if and only if the underlying class
1591 * is an anonymous class.
1592 *
1593 * @return {@code true} if and only if this class is an anonymous class.
1594 * @since 1.5
1595 */
1596 public boolean isAnonymousClass() {
1597 return "".equals(getSimpleName());
1598 }
1599
1600 /**
1601 * Returns {@code true} if and only if the underlying class
1602 * is a local class.
1603 *
1604 * @return {@code true} if and only if this class is a local class.
1605 * @since 1.5
1606 */
1607 public boolean isLocalClass() {
1608 return isLocalOrAnonymousClass() && !isAnonymousClass();
1609 }
1610
1611 /**
1612 * Returns {@code true} if and only if the underlying class
1613 * is a member class.
1614 *
1615 * @return {@code true} if and only if this class is a member class.
1616 * @since 1.5
1617 */
1618 public boolean isMemberClass() {
1619 return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
1620 }
1621
1622 /**
1623 * Returns the "simple binary name" of the underlying class, i.e.,
1624 * the binary name without the leading enclosing class name.
1625 * Returns {@code null} if the underlying class is a top level
1626 * class.
1627 */
1628 private String getSimpleBinaryName() {
1629 Class<?> enclosingClass = getEnclosingClass();
1630 if (enclosingClass == null) // top level class
1631 return null;
1632 String name = getSimpleBinaryName0();
1633 if (name == null) // anonymous class
1634 return "";
1635 return name;
1636 }
1637
1638 private native String getSimpleBinaryName0();
1639
1640 /**
1641 * Returns {@code true} if this is a local class or an anonymous
1642 * class. Returns {@code false} otherwise.
1643 */
1644 private boolean isLocalOrAnonymousClass() {
1645 // JVM Spec 4.7.7: A class must have an EnclosingMethod
1646 // attribute if and only if it is a local class or an
1647 // anonymous class.
1648 return getEnclosingMethodInfo() != null;
1649 }
1650
1651 /**
1652 * Returns an array containing {@code Class} objects representing all
1653 * the public classes and interfaces that are members of the class
1654 * represented by this {@code Class} object. This includes public
1655 * class and interface members inherited from superclasses and public class
1656 * and interface members declared by the class. This method returns an
1657 * array of length 0 if this {@code Class} object has no public member
1658 * classes or interfaces. This method also returns an array of length 0 if
1659 * this {@code Class} object represents a primitive type, an array
1660 * class, or void.
1661 *
1662 * @return the array of {@code Class} objects representing the public
1663 * members of this class
1664 * @throws SecurityException
1665 * If a security manager, <i>s</i>, is present and
1666 * the caller's class loader is not the same as or an
1667 * ancestor of the class loader for the current class and
1668 * invocation of {@link SecurityManager#checkPackageAccess
|
1255
1256 if (matches) { // finally, check return type
1257 if (m.getReturnType().equals(returnType) )
1258 return m;
1259 }
1260 }
1261 }
1262 }
1263
1264 throw new InternalError("Enclosing method not found");
1265 }
1266 }
1267
1268 private native Object[] getEnclosingMethod0();
1269
1270 private EnclosingMethodInfo getEnclosingMethodInfo() {
1271 Object[] enclosingInfo = getEnclosingMethod0();
1272 if (enclosingInfo == null)
1273 return null;
1274 else {
1275 return EnclosingMethodInfo.createEnclosingInfo(enclosingInfo);
1276 }
1277 }
1278
1279 private static final class EnclosingMethodInfo {
1280 private final Class<?> enclosingClass;
1281 private final String name;
1282 private final String descriptor;
1283
1284 static void checkEnclosingInfo(Object[] enclosingInfo) {
1285 if (enclosingInfo.length != 3)
1286 throw new InternalError("Malformed enclosing method information");
1287 try {
1288 // The array is expected to have three elements:
1289
1290 // the immediately enclosing class
1291 Class<?> enclosingClass = (Class<?>) enclosingInfo[0];
1292 assert(enclosingClass != null);
1293
1294 // the immediately enclosing method or constructor's
1295 // name (can be null).
1296 String name = (String) enclosingInfo[1];
1297
1298 // the immediately enclosing method or constructor's
1299 // descriptor (null iff name is).
1300 String descriptor = (String) enclosingInfo[2];
1301 assert((name != null && descriptor != null) || name == descriptor);
1302 } catch (ClassCastException cce) {
1303 throw new InternalError("Invalid type in enclosing method information", cce);
1304 }
1305 }
1306
1307 static EnclosingMethodInfo createEnclosingInfo(Object[] enclosingInfo) {
1308 checkEnclosingInfo(enclosingInfo);
1309 return new EnclosingMethodInfo((Class<?>)enclosingInfo[0],
1310 (String)enclosingInfo[1],
1311 (String)enclosingInfo[2]);
1312 }
1313
1314 private EnclosingMethodInfo(Class<?> enclosingClass, String name,
1315 String descriptor) {
1316 this.enclosingClass = enclosingClass;
1317 this.name = name;
1318 this.descriptor = descriptor;
1319 }
1320
1321 boolean isPartial() {
1322 return enclosingClass == null || name == null || descriptor == null;
1323 }
1324
1325 boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
1326
1327 boolean isMethod() { return !isPartial() && !isConstructor() && !"<clinit>".equals(name); }
1328
1329 Class<?> getEnclosingClass() { return enclosingClass; }
1330
1331 String getName() { return name; }
1332
1333 String getDescriptor() { return descriptor; }
1334
1335 }
1336
1337 private static Class<?> toClass(Type o) {
1338 if (o instanceof GenericArrayType)
1339 return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
1340 0)
1478 * @since 1.5
1479 */
1480 @CallerSensitive
1481 public Class<?> getEnclosingClass() throws SecurityException {
1482 // There are five kinds of classes (or interfaces):
1483 // a) Top level classes
1484 // b) Nested classes (static member classes)
1485 // c) Inner classes (non-static member classes)
1486 // d) Local classes (named classes declared within a method)
1487 // e) Anonymous classes
1488
1489
1490 // JVM Spec 4.7.7: A class must have an EnclosingMethod
1491 // attribute if and only if it is a local class or an
1492 // anonymous class.
1493 EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1494 Class<?> enclosingCandidate;
1495
1496 if (enclosingInfo == null) {
1497 // This is a top level or a nested class or an inner class (a, b, or c)
1498 enclosingCandidate = getDeclaringClass0();
1499 } else {
1500 Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1501 // This is a local class or an anonymous class (d or e)
1502 if (enclosingClass == this || enclosingClass == null)
1503 throw new InternalError("Malformed enclosing method information");
1504 else
1505 enclosingCandidate = enclosingClass;
1506 }
1507
1508 if (enclosingCandidate != null)
1509 enclosingCandidate.checkPackageAccess(
1510 ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
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 *
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 *
1611 * @return {@code true} if and only if this class is a local class.
1612 * @since 1.5
1613 */
1614 public boolean isLocalClass() {
1615 return isLocalOrAnonymousClass() &&
1616 (isArray() || getSimpleBinaryName0() != null);
1617 }
1618
1619 /**
1620 * Returns {@code true} if and only if the underlying class
1621 * is a member class.
1622 *
1623 * @return {@code true} if and only if this class is a member class.
1624 * @since 1.5
1625 */
1626 public boolean isMemberClass() {
1627 return !isLocalOrAnonymousClass() && getDeclaringClass0() != null;
1628 }
1629
1630 /**
1631 * Returns the "simple binary name" of the underlying class, i.e.,
1632 * the binary name without the leading enclosing class name.
1633 * Returns {@code null} if the underlying class is a top level
1634 * class.
1635 */
1636 private String getSimpleBinaryName() {
1637 if (isTopLevelClass())
1638 return null;
1639 String name = getSimpleBinaryName0();
1640 if (name == null) // anonymous class
1641 return "";
1642 return name;
1643 }
1644
1645 private native String getSimpleBinaryName0();
1646
1647 /**
1648 * Returns {@code true} if this is a top level class. Returns {@code false}
1649 * otherwise.
1650 */
1651 private boolean isTopLevelClass() {
1652 return !isLocalOrAnonymousClass() && getDeclaringClass0() == null;
1653 }
1654
1655 /**
1656 * Returns {@code true} if this is a local class or an anonymous
1657 * class. Returns {@code false} otherwise.
1658 */
1659 private boolean isLocalOrAnonymousClass() {
1660 // JVM Spec 4.7.7: A class must have an EnclosingMethod
1661 // attribute if and only if it is a local class or an
1662 // anonymous class.
1663 Object[] enclosingInfo = getEnclosingMethod0();
1664 if (enclosingInfo == null) {
1665 return false;
1666 } else {
1667 EnclosingMethodInfo.checkEnclosingInfo(enclosingInfo);
1668 return true;
1669 }
1670 }
1671
1672 /**
1673 * Returns an array containing {@code Class} objects representing all
1674 * the public classes and interfaces that are members of the class
1675 * represented by this {@code Class} object. This includes public
1676 * class and interface members inherited from superclasses and public class
1677 * and interface members declared by the class. This method returns an
1678 * array of length 0 if this {@code Class} object has no public member
1679 * classes or interfaces. This method also returns an array of length 0 if
1680 * this {@code Class} object represents a primitive type, an array
1681 * class, or void.
1682 *
1683 * @return the array of {@code Class} objects representing the public
1684 * members of this class
1685 * @throws SecurityException
1686 * If a security manager, <i>s</i>, is present and
1687 * the caller's class loader is not the same as or an
1688 * ancestor of the class loader for the current class and
1689 * invocation of {@link SecurityManager#checkPackageAccess
|