jdk/src/java.base/share/classes/java/lang/Class.java
changeset 30341 a026e34714ed
parent 29113 4c3e0acf325e
child 30365 551470085a1d
equal deleted inserted replaced
30340:d931e2237178 30341:a026e34714ed
  1310         // c) Inner classes (non-static member classes)
  1310         // c) Inner classes (non-static member classes)
  1311         // d) Local classes (named classes declared within a method)
  1311         // d) Local classes (named classes declared within a method)
  1312         // e) Anonymous classes
  1312         // e) Anonymous classes
  1313 
  1313 
  1314 
  1314 
  1315         // JVM Spec 4.8.6: A class must have an EnclosingMethod
  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
  1316         // attribute if and only if it is a local class or an
  1317         // anonymous class.
  1317         // anonymous class.
  1318         EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
  1318         EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
  1319         Class<?> enclosingCandidate;
  1319         Class<?> enclosingCandidate;
  1320 
  1320 
  1355         String simpleName = getSimpleBinaryName();
  1355         String simpleName = getSimpleBinaryName();
  1356         if (simpleName == null) { // top level class
  1356         if (simpleName == null) { // top level class
  1357             simpleName = getName();
  1357             simpleName = getName();
  1358             return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name
  1358             return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name
  1359         }
  1359         }
  1360         // According to JLS3 "Binary Compatibility" (13.1) the binary
  1360         return simpleName;
  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     }
  1361     }
  1383 
  1362 
  1384     /**
  1363     /**
  1385      * Return an informative string for the name of this type.
  1364      * Return an informative string for the name of this type.
  1386      *
  1365      *
  1487      */
  1466      */
  1488     private String getSimpleBinaryName() {
  1467     private String getSimpleBinaryName() {
  1489         Class<?> enclosingClass = getEnclosingClass();
  1468         Class<?> enclosingClass = getEnclosingClass();
  1490         if (enclosingClass == null) // top level class
  1469         if (enclosingClass == null) // top level class
  1491             return null;
  1470             return null;
  1492         // Otherwise, strip the enclosing class' name
  1471         String name = getSimpleBinaryName0();
  1493         try {
  1472         if (name == null) // anonymous class
  1494             return getName().substring(enclosingClass.getName().length());
  1473             return "";
  1495         } catch (IndexOutOfBoundsException ex) {
  1474         return name;
  1496             throw new InternalError("Malformed class name", ex);
  1475     }
  1497         }
  1476 
  1498     }
  1477     private native String getSimpleBinaryName0();
  1499 
  1478 
  1500     /**
  1479     /**
  1501      * Returns {@code true} if this is a local class or an anonymous
  1480      * Returns {@code true} if this is a local class or an anonymous
  1502      * class.  Returns {@code false} otherwise.
  1481      * class.  Returns {@code false} otherwise.
  1503      */
  1482      */
  1504     private boolean isLocalOrAnonymousClass() {
  1483     private boolean isLocalOrAnonymousClass() {
  1505         // JVM Spec 4.8.6: A class must have an EnclosingMethod
  1484         // JVM Spec 4.7.7: A class must have an EnclosingMethod
  1506         // attribute if and only if it is a local class or an
  1485         // attribute if and only if it is a local class or an
  1507         // anonymous class.
  1486         // anonymous class.
  1508         return getEnclosingMethodInfo() != null;
  1487         return getEnclosingMethodInfo() != null;
  1509     }
  1488     }
  1510 
  1489