下面列出了java.lang.reflect.Executable#getModifiers ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static int getMethodFlags(Executable method) {
int flags = FunctionInfo.NONE;
int modifiers = method.getModifiers();
if (Modifier.isAbstract(modifiers)) {
flags |= FunctionInfo.ABSTRACT;
}
if (Modifier.isFinal(modifiers)) {
flags |= FunctionInfo.FINAL;
}
if (Modifier.isPublic(modifiers)) {
flags |= FunctionInfo.PUBLIC;
} else if (Modifier.isProtected(modifiers)) {
flags |= FunctionInfo.PROTECTED;
} else if (Modifier.isPrivate(modifiers)) {
flags |= FunctionInfo.PRIVATE;
} else {
flags |= FunctionInfo.DEFAULT;
}
if (Modifier.isStatic(modifiers)) {
flags |= FunctionInfo.STATIC;
}
if (Modifier.isSynchronized(modifiers)) {
flags |= FunctionInfo.SYNCHRONIZED;
}
return flags;
}
private static void runSanityTest(Executable aMethod) {
HotSpotResolvedJavaMethod method = CTVMUtilities
.getResolvedMethod(aMethod);
byte[] bytecode = CompilerToVMHelper.getBytecode(method);
int mods = aMethod.getModifiers();
boolean shouldHasZeroLength = Modifier.isAbstract(mods)
|| Modifier.isNative(mods);
boolean correctLength = (bytecode.length == 0 && shouldHasZeroLength)
|| (bytecode.length > 0 && !shouldHasZeroLength);
Asserts.assertTrue(correctLength, "Bytecode of '" + aMethod + "' has "
+ bytecode.length + " length");
if (!shouldHasZeroLength) {
Asserts.assertTrue(containsReturn(bytecode), "Bytecode of '"
+ aMethod + "' doesn't have any return statement");
}
}
/**
* Checks whether a method/constructor can be called with the given argument classes. This includes type
* widening and vararg. {@code null} is a wildcard.
*
* <p>E.g., {@code (int.class, int.class)} matches {@code f(Object...), f(int, int), f(Integer, Object)}
* and so forth.
*/
public static boolean isInvokable(Executable executable, Class<?>... classes) {
final int m = executable.getModifiers();
if (!Modifier.isPublic(m)) {
return false;
}
final int paramCount = executable.getParameterCount();
final int classCount = classes.length;
// check for enough classes for each parameter
if (classCount < paramCount || (executable.isVarArgs() && classCount < paramCount - 1)) {
return false;
}
int currentClass = 0;
for (int currentParam = 0; currentParam < paramCount; currentParam++) {
final Class<?> param = executable.getParameterTypes()[currentParam];
// entire parameter matches
if (classes[currentClass] == null || ExtractionUtils.isAssignable(classes[currentClass], param, true)) {
currentClass++;
}
// last parameter is a vararg that consumes remaining classes
else if (currentParam == paramCount - 1 && executable.isVarArgs()) {
final Class<?> paramComponent = executable.getParameterTypes()[currentParam].getComponentType();
while (currentClass < classCount && ExtractionUtils.isAssignable(classes[currentClass], paramComponent, true)) {
currentClass++;
}
}
}
// check if all classes have been consumed
return currentClass == classCount;
}
/**
* Checks whether the referenced method would be visible by an unrelated class in the same package
* as the currently visited class.
*/
private boolean isVisibleToLambdaClass(Executable invoked, String owner) {
int modifiers = invoked.getModifiers();
if (Modifier.isPrivate(modifiers)) {
return false;
}
if (Modifier.isPublic(modifiers)) {
return true;
}
// invoked is protected or package-private, either way we need it to be in the same package
// because the additional visibility protected gives doesn't help lambda classes, which are in
// a different class hierarchy (and typically just extend Object)
return packageName(internalName).equals(packageName(owner));
}