下面列出了java.lang.invoke.MethodHandles#publicLookup ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Subclasses may override doVisitListEnd
*/
@Override
public void visitEnd(String elementName, List<? extends Visitable> visitables, Class<?> type) {
doVisitListEnd(elementName, visitables, type);
ListWrapper listWrapper = listStack.pop();
if (listWrapper.isDirty()) {
BuilderWrapper parent = builderStack.peek();
parent.dirty(true);
Builder<?> parentBuilder = parent.getBuilder();
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
MethodType mt = MethodType.methodType(parentBuilder.getClass(), java.util.Collection.class);
MethodHandle methodHandle;
try {
methodHandle = lookup.findVirtual(parentBuilder.getClass(), setterName(elementName), mt);
methodHandle.invoke(parentBuilder, listWrapper.getList());
} catch (Throwable t) {
throw new RuntimeException("Unexpected error while visiting " + parentBuilder.getClass() + "." + elementName, t);
}
}
}
/**
* MethodHandles.publicLookup()
*
* [A0] has PUBLIC|UNCONDITIONAL access
*/
public void testPublicLookup() throws Exception {
Lookup lookup = MethodHandles.publicLookup();
assertTrue(lookup.lookupModes() == (PUBLIC|UNCONDITIONAL)); // A0
// m1
findConstructor(lookup, p1_Type1, void.class);
findConstructorExpectingIAE(lookup, p2_Type2, void.class);
// m2
findConstructor(lookup, q1_Type1, void.class);
findConstructorExpectingIAE(lookup, q2_Type2, void.class);
// java.base
findConstructor(lookup, Object.class, void.class);
findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
// unnamed
findConstructor(lookup, unnamedClass, void.class);
}
private static java.lang.invoke.MethodHandles.Lookup getCurrentLookup() {
final LinkRequest currentRequest = AccessController.doPrivileged(new PrivilegedAction<LinkRequest>() {
@Override
public LinkRequest run() {
return LinkerServicesImpl.getCurrentLinkRequest();
}
});
return currentRequest == null ? MethodHandles.publicLookup() : currentRequest.getCallSiteDescriptor().getLookup();
}
void callMethodHandleRefl() {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
try {
MethodHandle mh = lookup.findStatic(GetCallerClassTest.class,
"reflectiveGetCallerClass",
methodType);
mh.invokeExact(walker, ReflectionTest.class, expectUOE);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
private static Lookup getCurrentLookup() {
final LinkRequest currentRequest = AccessController.doPrivileged(new PrivilegedAction<LinkRequest>() {
@Override
public LinkRequest run() {
return LinkerServicesImpl.getCurrentLinkRequest();
}
});
return currentRequest == null ? MethodHandles.publicLookup() : currentRequest.getCallSiteDescriptor().getLookup();
}
private RpcMethod(INSTANCE instance, Method method, String[] parameterNames,String methodName,
boolean returnTypeJdk9PublisherFlag, boolean returnTypeReactivePublisherFlag,
boolean returnRxjava3ObservableFlag, boolean returnRxjava3FlowableFlag) {
this.instance = instance;
this.method = method;
this.methodName = methodName;
this.parameterNames = parameterNames;
this.returnTypeJdk9PublisherFlag = returnTypeJdk9PublisherFlag;
this.returnTypeReactivePublisherFlag = returnTypeReactivePublisherFlag;
this.returnRxjava3ObservableFlag = returnRxjava3ObservableFlag;
this.returnRxjava3FlowableFlag = returnRxjava3FlowableFlag;
this.returnCompletableFutureFlag = CompletableFuture.class.isAssignableFrom(method.getReturnType());
this.returnCompletionStageFlag = CompletionStage.class.isAssignableFrom(method.getReturnType());
this.returnFutureFlag = Future.class.isAssignableFrom(method.getReturnType());
this.parameterTypes = method.getParameterTypes();
if(returnTypeJdk9PublisherFlag || returnTypeReactivePublisherFlag
|| returnRxjava3ObservableFlag || returnRxjava3FlowableFlag
|| returnCompletableFutureFlag || returnCompletionStageFlag || returnFutureFlag){
this.genericReturnType = getParameterizedType(method);
}else {
this.genericReturnType = method.getGenericReturnType();
}
this.innerMethodFlag = RpcServerInstance.isRpcInnerClass(method.getDeclaringClass());
this.parameterTypeDescriptorName = Stream.of(parameterTypes)
.map(Class::getSimpleName)
.collect(Collectors.joining(","));
this.methodDescriptorName = getMethodDescriptorName(method);
this.parameterCount = method.getParameterCount();
MethodHandle methodHandle;
try {
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
MethodType methodType = MethodType.methodType(method.getReturnType(), method.getParameterTypes());
methodHandle = publicLookup.findVirtual(method.getDeclaringClass(), method.getName(), methodType);
} catch (NoSuchMethodException | IllegalAccessException e) {
methodHandle = null;
}
this.methodHandle = methodHandle;
}
@Test
public void givenReplaceMethodHandle_whenInvoked_thenCorrectlyReplaced() throws Throwable {
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
MethodType mt = MethodType.methodType(String.class, char.class, char.class);
MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
String replacedString = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a');
assertEquals("java", replacedString);
}
@Test
public void givenAsListMethodHandle_whenInvokingWithArguments_thenCorrectlyInvoked() throws Throwable {
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
MethodType mt = MethodType.methodType(List.class, Object[].class);
MethodHandle asListMH = publicLookup.findStatic(Arrays.class, "asList", mt);
List<Integer> list = (List<Integer>) asListMH.invokeWithArguments(1, 2);
assertThat(Arrays.asList(1, 2), is(list));
}
@Test
public void givenConcatMethodHandle_whenBindToAString_thenCorrectlyConcatenated() throws Throwable {
MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
MethodType mt = MethodType.methodType(String.class, String.class);
MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt);
MethodHandle bindedConcatMH = concatMH.bindTo("Hello ");
assertEquals("Hello World!", bindedConcatMH.invoke("World!"));
}
void callMethodHandle() {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
try {
MethodHandle mh = lookup.findStatic(GetCallerClassTest.class,
"staticGetCallerClass",
methodType);
mh.invokeExact(walker, ReflectionTest.class, expectUOE);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
private static boolean isPublicLookup(final Lookup lookup) {
return lookup == MethodHandles.publicLookup();
}
protected MethodHandles.Lookup lookup() {
return MethodHandles.publicLookup();
}
public static Object invoke(String methodName, Object... recvAndArgs) {
// TODO(springerm): Proper exception handling
// TODO(springerm): Need to do Dart type checks for arguments
// TODO(springerm): Special case methods defined on DartObject
try {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
Object receiver = recvAndArgs[0];
Class<?> receiverClass = receiver.getClass();
boolean checkForOverloads = false;
// TODO(springerm): Handle static methods properly
// The index of the first argument. When calling a static method, the
// first argument starts at index 0, because no "self" object is passed
int startArgs = 1;
if (classImpls.containsKey(receiverClass)) {
receiverClass = classImpls.get(receiverClass);
// There may be multiple overloadings for operators, we have to
// pick the correct one
checkForOverloads = true;
startArgs = 0;
} else if (classesWithJavaInterfaces.contains(receiverClass)) {
checkForOverloads = true;
}
// TODO(springerm): Try to use MethodHandles API for lookup
// TODO(springerm): Look into byte code generation for invokedynamic
Method method = null;
methodLoop:
for (Method m : receiverClass.getMethods()) {
if (m.getName().equals(methodName)) {
if (checkForOverloads) {
Class<?>[] parameterTypes = m.getParameterTypes();
// Check if the number of parameters match
if (parameterTypes.length != recvAndArgs.length - startArgs) {
continue methodLoop;
}
// Check if the parameter types for this method match
for (int i = startArgs; i < parameterTypes.length; i++) {
if (!parameterTypes[i - startArgs].isAssignableFrom(
boxedToMaybeUnboxedType(recvAndArgs[i].getClass()))
&& !parameterTypes[i - startArgs].isAssignableFrom(
recvAndArgs[i].getClass())) {
// Picked the wrong method, continue searching
continue methodLoop;
}
}
}
// Found matching method
method = m;
break methodLoop;
}
}
if (method == null) {
String argTypes = "";
for (Object o : recvAndArgs) {
argTypes = argTypes + o.getClass().getName() + ", ";
}
throw new NoSuchMethodException(
receiverClass.getName() + "." + methodName
+ " (" + argTypes + ") not found");
}
MethodHandle handle = lookup.unreflect(method);
MethodHandle handleSpreader = handle.asSpreader(
Object[].class, recvAndArgs.length);
Object result = handleSpreader.invoke(recvAndArgs);
return result;
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private static LinkRequest createLinkRequest(final Operation operation, final MethodType methodType, final Object source) {
return new SimpleLinkRequest(new CallSiteDescriptor(MethodHandles.publicLookup(), operation,
methodType), false, source);
}
@Override
public Lookup getLookup() {
return MethodHandles.publicLookup();
}
private static boolean isPublicLookup(final Lookup lookup) {
return lookup == MethodHandles.publicLookup();
}
@Override
public Lookup getLookup() {
return MethodHandles.publicLookup();
}
private static boolean isPublicLookup(final Lookup lookup) {
return lookup == MethodHandles.publicLookup();
}
@Override
public Lookup getLookup() {
return MethodHandles.publicLookup();
}
@Override
public Lookup getLookup() {
return MethodHandles.publicLookup();
}