< prev index next >
src/java.base/share/classes/java/lang/Class.java
Print this page
rev 16182 : 8170595: Optimize Class.isAnonymousClass
Reviewed-by: mchung
Contributed-by: claes.redestad@oracle.com, christoph.dreis@freenet.de
*** 1270,1311 ****
private EnclosingMethodInfo getEnclosingMethodInfo() {
Object[] enclosingInfo = getEnclosingMethod0();
if (enclosingInfo == null)
return null;
else {
! return new EnclosingMethodInfo(enclosingInfo);
}
}
private static final class EnclosingMethodInfo {
! private Class<?> enclosingClass;
! private String name;
! private String descriptor;
! private EnclosingMethodInfo(Object[] enclosingInfo) {
if (enclosingInfo.length != 3)
throw new InternalError("Malformed enclosing method information");
try {
// The array is expected to have three elements:
// the immediately enclosing class
! enclosingClass = (Class<?>) enclosingInfo[0];
assert(enclosingClass != null);
// the immediately enclosing method or constructor's
// name (can be null).
! name = (String) enclosingInfo[1];
// the immediately enclosing method or constructor's
// descriptor (null iff name is).
! descriptor = (String) enclosingInfo[2];
assert((name != null && descriptor != null) || name == descriptor);
} catch (ClassCastException cce) {
throw new InternalError("Invalid type in enclosing method information", cce);
}
}
boolean isPartial() {
return enclosingClass == null || name == null || descriptor == null;
}
boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
--- 1270,1325 ----
private EnclosingMethodInfo getEnclosingMethodInfo() {
Object[] enclosingInfo = getEnclosingMethod0();
if (enclosingInfo == null)
return null;
else {
! return EnclosingMethodInfo.createEnclosingInfo(enclosingInfo);
}
}
private static final class EnclosingMethodInfo {
! private final Class<?> enclosingClass;
! private final String name;
! private final String descriptor;
! static void checkEnclosingInfo(Object[] enclosingInfo) {
if (enclosingInfo.length != 3)
throw new InternalError("Malformed enclosing method information");
try {
// The array is expected to have three elements:
// the immediately enclosing class
! Class<?> enclosingClass = (Class<?>) enclosingInfo[0];
assert(enclosingClass != null);
// the immediately enclosing method or constructor's
// name (can be null).
! String name = (String) enclosingInfo[1];
// the immediately enclosing method or constructor's
// descriptor (null iff name is).
! String descriptor = (String) enclosingInfo[2];
assert((name != null && descriptor != null) || name == descriptor);
} catch (ClassCastException cce) {
throw new InternalError("Invalid type in enclosing method information", cce);
}
}
+ static EnclosingMethodInfo createEnclosingInfo(Object[] enclosingInfo) {
+ checkEnclosingInfo(enclosingInfo);
+ return new EnclosingMethodInfo((Class<?>)enclosingInfo[0],
+ (String)enclosingInfo[1],
+ (String)enclosingInfo[2]);
+ }
+
+ private EnclosingMethodInfo(Class<?> enclosingClass, String name,
+ String descriptor) {
+ this.enclosingClass = enclosingClass;
+ this.name = name;
+ this.descriptor = descriptor;
+ }
+
boolean isPartial() {
return enclosingClass == null || name == null || descriptor == null;
}
boolean isConstructor() { return !isPartial() && "<init>".equals(name); }
*** 1479,1489 ****
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
Class<?> enclosingCandidate;
if (enclosingInfo == null) {
// This is a top level or a nested class or an inner class (a, b, or c)
! enclosingCandidate = getDeclaringClass();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// This is a local class or an anonymous class (d or e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("Malformed enclosing method information");
--- 1493,1503 ----
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
Class<?> enclosingCandidate;
if (enclosingInfo == null) {
// This is a top level or a nested class or an inner class (a, b, or c)
! enclosingCandidate = getDeclaringClass0();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// This is a local class or an anonymous class (d or e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("Malformed enclosing method information");
*** 1546,1563 ****
}
return getName();
}
/**
- * Character.isDigit answers {@code true} to some non-ascii
- * digits. This one does not.
- */
- private static boolean isAsciiDigit(char c) {
- return '0' <= c && c <= '9';
- }
-
- /**
* Returns the canonical name of the underlying class as
* defined by the Java Language Specification. Returns null if
* the underlying class does not have a canonical name (i.e., if
* it is a local or anonymous class or an array whose component
* type does not have a canonical name).
--- 1560,1569 ----
*** 1592,1653 ****
*
* @return {@code true} if and only if this class is an anonymous class.
* @since 1.5
*/
public boolean isAnonymousClass() {
! return "".equals(getSimpleName());
}
/**
* Returns {@code true} if and only if the underlying class
* is a local class.
*
* @return {@code true} if and only if this class is a local class.
* @since 1.5
*/
public boolean isLocalClass() {
! return isLocalOrAnonymousClass() && !isAnonymousClass();
}
/**
* Returns {@code true} if and only if the underlying class
* is a member class.
*
* @return {@code true} if and only if this class is a member class.
* @since 1.5
*/
public boolean isMemberClass() {
! return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
}
/**
* Returns the "simple binary name" of the underlying class, i.e.,
* the binary name without the leading enclosing class name.
* Returns {@code null} if the underlying class is a top level
* class.
*/
private String getSimpleBinaryName() {
! Class<?> enclosingClass = getEnclosingClass();
! if (enclosingClass == null) // top level class
return null;
String name = getSimpleBinaryName0();
if (name == null) // anonymous class
return "";
return name;
}
private native String getSimpleBinaryName0();
/**
* Returns {@code true} if this is a local class or an anonymous
* class. Returns {@code false} otherwise.
*/
private boolean isLocalOrAnonymousClass() {
// JVM Spec 4.7.7: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
! return getEnclosingMethodInfo() != null;
}
/**
* Returns an array containing {@code Class} objects representing all
* the public classes and interfaces that are members of the class
--- 1598,1674 ----
*
* @return {@code true} if and only if this class is an anonymous class.
* @since 1.5
*/
public boolean isAnonymousClass() {
! return !isArray() && isLocalOrAnonymousClass() &&
! getSimpleBinaryName0() == null;
}
/**
* Returns {@code true} if and only if the underlying class
* is a local class.
*
* @return {@code true} if and only if this class is a local class.
* @since 1.5
*/
public boolean isLocalClass() {
! return isLocalOrAnonymousClass() &&
! (isArray() || getSimpleBinaryName0() != null);
}
/**
* Returns {@code true} if and only if the underlying class
* is a member class.
*
* @return {@code true} if and only if this class is a member class.
* @since 1.5
*/
public boolean isMemberClass() {
! return !isLocalOrAnonymousClass() && getDeclaringClass0() != null;
}
/**
* Returns the "simple binary name" of the underlying class, i.e.,
* the binary name without the leading enclosing class name.
* Returns {@code null} if the underlying class is a top level
* class.
*/
private String getSimpleBinaryName() {
! if (isTopLevelClass())
return null;
String name = getSimpleBinaryName0();
if (name == null) // anonymous class
return "";
return name;
}
private native String getSimpleBinaryName0();
/**
+ * Returns {@code true} if this is a top level class. Returns {@code false}
+ * otherwise.
+ */
+ private boolean isTopLevelClass() {
+ return !isLocalOrAnonymousClass() && getDeclaringClass0() == null;
+ }
+
+ /**
* Returns {@code true} if this is a local class or an anonymous
* class. Returns {@code false} otherwise.
*/
private boolean isLocalOrAnonymousClass() {
// JVM Spec 4.7.7: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
! Object[] enclosingInfo = getEnclosingMethod0();
! if (enclosingInfo == null) {
! return false;
! } else {
! EnclosingMethodInfo.checkEnclosingInfo(enclosingInfo);
! return true;
! }
}
/**
* Returns an array containing {@code Class} objects representing all
* the public classes and interfaces that are members of the class
< prev index next >