< prev index next >

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

Print this page




1295      * method returns {@code null}.
1296      * @return the immediately enclosing class of the underlying class
1297      * @exception  SecurityException
1298      *             If a security manager, <i>s</i>, is present and the caller's
1299      *             class loader is not the same as or an ancestor of the class
1300      *             loader for the enclosing class and invocation of {@link
1301      *             SecurityManager#checkPackageAccess s.checkPackageAccess()}
1302      *             denies access to the package of the enclosing class
1303      * @since 1.5
1304      */
1305     @CallerSensitive
1306     public Class<?> getEnclosingClass() throws SecurityException {
1307         // There are five kinds of classes (or interfaces):
1308         // a) Top level classes
1309         // b) Nested classes (static member classes)
1310         // c) Inner classes (non-static member classes)
1311         // d) Local classes (named classes declared within a method)
1312         // e) Anonymous classes
1313 
1314 
1315         // JVM Spec 4.8.6: A class must have an EnclosingMethod
1316         // attribute if and only if it is a local class or an
1317         // anonymous class.
1318         EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1319         Class<?> enclosingCandidate;
1320 
1321         if (enclosingInfo == null) {
1322             // This is a top level or a nested class or an inner class (a, b, or c)
1323             enclosingCandidate = getDeclaringClass();
1324         } else {
1325             Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1326             // This is a local class or an anonymous class (d or e)
1327             if (enclosingClass == this || enclosingClass == null)
1328                 throw new InternalError("Malformed enclosing method information");
1329             else
1330                 enclosingCandidate = enclosingClass;
1331         }
1332 
1333         if (enclosingCandidate != null)
1334             enclosingCandidate.checkPackageAccess(
1335                     ClassLoader.getClassLoader(Reflection.getCallerClass()), true);


1340      * Returns the simple name of the underlying class as given in the
1341      * source code. Returns an empty string if the underlying class is
1342      * anonymous.
1343      *
1344      * <p>The simple name of an array is the simple name of the
1345      * component type with "[]" appended.  In particular the simple
1346      * name of an array whose component type is anonymous is "[]".
1347      *
1348      * @return the simple name of the underlying class
1349      * @since 1.5
1350      */
1351     public String getSimpleName() {
1352         if (isArray())
1353             return getComponentType().getSimpleName()+"[]";
1354 
1355         String simpleName = getSimpleBinaryName();
1356         if (simpleName == null) { // top level class
1357             simpleName = getName();
1358             return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name
1359         }
1360         // According to JLS3 "Binary Compatibility" (13.1) the binary
1361         // name of non-package classes (not top level) is the binary
1362         // name of the immediately enclosing class followed by a '$' followed by:
1363         // (for nested and inner classes): the simple name.
1364         // (for local classes): 1 or more digits followed by the simple name.
1365         // (for anonymous classes): 1 or more digits.
1366 
1367         // Since getSimpleBinaryName() will strip the binary name of
1368         // the immediately enclosing class, we are now looking at a
1369         // string that matches the regular expression "\$[0-9]*"
1370         // followed by a simple name (considering the simple of an
1371         // anonymous class to be the empty string).
1372 
1373         // Remove leading "\$[0-9]*" from the name
1374         int length = simpleName.length();
1375         if (length < 1 || simpleName.charAt(0) != '$')
1376             throw new InternalError("Malformed class name");
1377         int index = 1;
1378         while (index < length && isAsciiDigit(simpleName.charAt(index)))
1379             index++;
1380         // Eventually, this is the empty string iff this is an anonymous class
1381         return simpleName.substring(index);
1382     }
1383 
1384     /**
1385      * Return an informative string for the name of this type.
1386      *
1387      * @return an informative string for the name of this type
1388      * @since 1.8
1389      */
1390     public String getTypeName() {
1391         if (isArray()) {
1392             try {
1393                 Class<?> cl = this;
1394                 int dimensions = 0;
1395                 while (cl.isArray()) {
1396                     dimensions++;
1397                     cl = cl.getComponentType();
1398                 }
1399                 StringBuilder sb = new StringBuilder();
1400                 sb.append(cl.getName());
1401                 for (int i = 0; i < dimensions; i++) {


1472      * Returns {@code true} if and only if the underlying class
1473      * is a member class.
1474      *
1475      * @return {@code true} if and only if this class is a member class.
1476      * @since 1.5
1477      */
1478     public boolean isMemberClass() {
1479         return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
1480     }
1481 
1482     /**
1483      * Returns the "simple binary name" of the underlying class, i.e.,
1484      * the binary name without the leading enclosing class name.
1485      * Returns {@code null} if the underlying class is a top level
1486      * class.
1487      */
1488     private String getSimpleBinaryName() {
1489         Class<?> enclosingClass = getEnclosingClass();
1490         if (enclosingClass == null) // top level class
1491             return null;
1492         // Otherwise, strip the enclosing class' name
1493         try {
1494             return getName().substring(enclosingClass.getName().length());
1495         } catch (IndexOutOfBoundsException ex) {
1496             throw new InternalError("Malformed class name", ex);
1497         }
1498     }
1499 


1500     /**
1501      * Returns {@code true} if this is a local class or an anonymous
1502      * class.  Returns {@code false} otherwise.
1503      */
1504     private boolean isLocalOrAnonymousClass() {
1505         // JVM Spec 4.8.6: A class must have an EnclosingMethod
1506         // attribute if and only if it is a local class or an
1507         // anonymous class.
1508         return getEnclosingMethodInfo() != null;
1509     }
1510 
1511     /**
1512      * Returns an array containing {@code Class} objects representing all
1513      * the public classes and interfaces that are members of the class
1514      * represented by this {@code Class} object.  This includes public
1515      * class and interface members inherited from superclasses and public class
1516      * and interface members declared by the class.  This method returns an
1517      * array of length 0 if this {@code Class} object has no public member
1518      * classes or interfaces.  This method also returns an array of length 0 if
1519      * this {@code Class} object represents a primitive type, an array
1520      * class, or void.
1521      *
1522      * @return the array of {@code Class} objects representing the public
1523      *         members of this class
1524      * @throws SecurityException
1525      *         If a security manager, <i>s</i>, is present and




1295      * method returns {@code null}.
1296      * @return the immediately enclosing class of the underlying class
1297      * @exception  SecurityException
1298      *             If a security manager, <i>s</i>, is present and the caller's
1299      *             class loader is not the same as or an ancestor of the class
1300      *             loader for the enclosing class and invocation of {@link
1301      *             SecurityManager#checkPackageAccess s.checkPackageAccess()}
1302      *             denies access to the package of the enclosing class
1303      * @since 1.5
1304      */
1305     @CallerSensitive
1306     public Class<?> getEnclosingClass() throws SecurityException {
1307         // There are five kinds of classes (or interfaces):
1308         // a) Top level classes
1309         // b) Nested classes (static member classes)
1310         // c) Inner classes (non-static member classes)
1311         // d) Local classes (named classes declared within a method)
1312         // e) Anonymous classes
1313 
1314 
1315         // JVM Spec 4.7.7: A class must have an EnclosingMethod
1316         // attribute if and only if it is a local class or an
1317         // anonymous class.
1318         EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
1319         Class<?> enclosingCandidate;
1320 
1321         if (enclosingInfo == null) {
1322             // This is a top level or a nested class or an inner class (a, b, or c)
1323             enclosingCandidate = getDeclaringClass();
1324         } else {
1325             Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
1326             // This is a local class or an anonymous class (d or e)
1327             if (enclosingClass == this || enclosingClass == null)
1328                 throw new InternalError("Malformed enclosing method information");
1329             else
1330                 enclosingCandidate = enclosingClass;
1331         }
1332 
1333         if (enclosingCandidate != null)
1334             enclosingCandidate.checkPackageAccess(
1335                     ClassLoader.getClassLoader(Reflection.getCallerClass()), true);


1340      * Returns the simple name of the underlying class as given in the
1341      * source code. Returns an empty string if the underlying class is
1342      * anonymous.
1343      *
1344      * <p>The simple name of an array is the simple name of the
1345      * component type with "[]" appended.  In particular the simple
1346      * name of an array whose component type is anonymous is "[]".
1347      *
1348      * @return the simple name of the underlying class
1349      * @since 1.5
1350      */
1351     public String getSimpleName() {
1352         if (isArray())
1353             return getComponentType().getSimpleName()+"[]";
1354 
1355         String simpleName = getSimpleBinaryName();
1356         if (simpleName == null) { // top level class
1357             simpleName = getName();
1358             return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name
1359         }
1360         return simpleName;





















1361     }
1362 
1363     /**
1364      * Return an informative string for the name of this type.
1365      *
1366      * @return an informative string for the name of this type
1367      * @since 1.8
1368      */
1369     public String getTypeName() {
1370         if (isArray()) {
1371             try {
1372                 Class<?> cl = this;
1373                 int dimensions = 0;
1374                 while (cl.isArray()) {
1375                     dimensions++;
1376                     cl = cl.getComponentType();
1377                 }
1378                 StringBuilder sb = new StringBuilder();
1379                 sb.append(cl.getName());
1380                 for (int i = 0; i < dimensions; i++) {


1451      * Returns {@code true} if and only if the underlying class
1452      * is a member class.
1453      *
1454      * @return {@code true} if and only if this class is a member class.
1455      * @since 1.5
1456      */
1457     public boolean isMemberClass() {
1458         return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
1459     }
1460 
1461     /**
1462      * Returns the "simple binary name" of the underlying class, i.e.,
1463      * the binary name without the leading enclosing class name.
1464      * Returns {@code null} if the underlying class is a top level
1465      * class.
1466      */
1467     private String getSimpleBinaryName() {
1468         Class<?> enclosingClass = getEnclosingClass();
1469         if (enclosingClass == null) // top level class
1470             return null;
1471         String name = getSimpleBinaryName0();
1472         if (name == null) // anonymous class
1473             return "";
1474         return name;


1475     }
1476 
1477     private native String getSimpleBinaryName0();
1478 
1479     /**
1480      * Returns {@code true} if this is a local class or an anonymous
1481      * class.  Returns {@code false} otherwise.
1482      */
1483     private boolean isLocalOrAnonymousClass() {
1484         // JVM Spec 4.7.7: A class must have an EnclosingMethod
1485         // attribute if and only if it is a local class or an
1486         // anonymous class.
1487         return getEnclosingMethodInfo() != null;
1488     }
1489 
1490     /**
1491      * Returns an array containing {@code Class} objects representing all
1492      * the public classes and interfaces that are members of the class
1493      * represented by this {@code Class} object.  This includes public
1494      * class and interface members inherited from superclasses and public class
1495      * and interface members declared by the class.  This method returns an
1496      * array of length 0 if this {@code Class} object has no public member
1497      * classes or interfaces.  This method also returns an array of length 0 if
1498      * this {@code Class} object represents a primitive type, an array
1499      * class, or void.
1500      *
1501      * @return the array of {@code Class} objects representing the public
1502      *         members of this class
1503      * @throws SecurityException
1504      *         If a security manager, <i>s</i>, is present and


< prev index next >