我如何通过获得所有声明的方法MethodHandles.lookup()?如何获取所有声明的字段?
MethodHandles.lookup()
有什么区别MethodHandle.invoke(),MethodHandle.invokeExact()和MethodHandle.invokeWithArguments()
MethodHandle.invoke()
MethodHandle.invokeExact()
MethodHandle.invokeWithArguments()
另外,对于使用MethodHandle API for Java devloper的 教程,我将不胜感激。我强调,我是在使用静态类型语言的普通Java上编程的,并且我不是JVM开发人员,尤其是我对整个字节码废话(invokedynamic)不感兴趣。我想弄清楚如何使用此新API代替Java Core API。
编辑2:
下面的@Glen Best提供了一些参考,我只想提供一个http://www.oraclejavamagazine- digital.com/javamagazine/20130102?pg=52&search_term=methodhandle&doc_id=-1#pg50这正是我在寻找的东西。我发现实际上存在一些新词汇。例如, 目标 实际上是MethodHandle(而不是要进行分派的对象),而 调用站点 实际上是“调用”“函数指针”(又称为MethodHandle)的代码。此外,它是一定要了解MethodHandle API是 不是更换为 核心映像API,而不是 suplement 它。例如,您不能使用需要Core Reflection API的MethodHandle来“发现”所有方法。但是,当您“查找”所需的方法时,可以切换到MethodHandle,例如,将其某些参数绑定或将其签名“更改”(适应)到varargs。
编辑:
我仍在尝试找出答案。我写了一些我想与所有人共享的测试。
package alexander.berkovich; import static org.junit.Assert.assertSame; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.BeforeClass; import org.junit.Test; public class MethodHandlerCleanTest { public static MethodHandles.Lookup lookup; @BeforeClass public static void asetUp(){ lookup = MethodHandles.lookup(); } public static class Check { public void primitive(final int i){ } public void wrapper(final Integer i){ } } @Test public void testPrimitive() throws Throwable { Check check = new Check(); MethodType type = MethodType.methodType(void.class, int.class); MethodHandle mh = lookup.findVirtual(Check.class, "primitive", type); mh.invokeWithArguments(check, 1); mh.invoke(check, (short)2); mh.invoke(check, Integer.valueOf(3)); Method method = Check.class.getMethod("primitive", int.class); method.invoke(check, (short)20); method.invoke(check, Integer.valueOf(21)); } @Test public void testWrapper() throws Throwable { Check check = new Check(); MethodType type = MethodType.methodType(void.class, Integer.class); MethodHandle mh = lookup.findVirtual(Check.class, "wrapper", type); mh.invoke(check, 2); Method method = Check.class.getMethod("wrapper", Integer.class); method.invoke(check, 20); } @SuppressWarnings("unused") public static class StaticInnerClass { public static String staticName; public String name; public void foo(){} public static void staticFoo(){} } @Test public void testStaticInnerClassStaticField() throws Throwable { MethodHandle mhSet = lookup.findStaticSetter(StaticInnerClass.class, "staticName", String.class); String expected = "mama"; mhSet.invoke(expected); MethodHandle mhGet = lookup.findStaticGetter(StaticInnerClass.class, "staticName", String.class); Object obj = mhGet.invoke(); String value = (String)obj; assertSame(expected, value); } @Test public void testStaticInnerClassField() throws Throwable { StaticInnerClass sut = new StaticInnerClass(); Field f = StaticInnerClass.class.getDeclaredField("name"); MethodHandle mhSetUnreflect = lookup.unreflectSetter(f); String expectedUnreflect = "unreflect"; mhSetUnreflect.invoke(sut, expectedUnreflect); MethodHandle mhSet = lookup.findSetter(StaticInnerClass.class, "name", String.class); String expected = "mama"; mhSet.invoke(sut, expected); MethodHandle mhGet = lookup.findGetter(StaticInnerClass.class, "name", String.class); Object obj = mhGet.invoke(sut); String value = (String)obj; assertSame(expected, value); } @Test public void testStaticInnerClassConstructor() throws Throwable { StaticInnerClass sut = new StaticInnerClass(); MethodType type = MethodType.methodType(void.class); MethodHandle mh = lookup.findConstructor(StaticInnerClass.class, type); mh.invoke(); } @Test public void testStaticInnerClassMethod() throws Throwable { StaticInnerClass sut = new StaticInnerClass(); MethodType type = MethodType.methodType(void.class); MethodHandle mh = lookup.findVirtual(StaticInnerClass.class, "foo", type); mh.invoke(sut); } @Test public void testStaticInnerClassStaticMethod() throws Throwable { MethodType type = MethodType.methodType(void.class); MethodHandle mh = lookup.findStatic(StaticInnerClass.class, "staticFoo", type); mh.invoke(); } @SuppressWarnings("unused") private class InnerClass { public String name; public void foo(){} } @Test public void testInnerClassField() throws Throwable { InnerClass sut = new InnerClass(); MethodHandle mhSet = lookup.findSetter(InnerClass.class, "name", String.class); String expected = "mama"; mhSet.invoke(sut, expected); MethodHandle mhGet = lookup.findGetter(InnerClass.class, "name", String.class); Object obj = mhGet.invoke(sut); String value = (String)obj; assertSame(expected, value); } @Test public void testInnerClassConstructor() throws Throwable { MethodType type = MethodType.methodType(void.class, MethodHandlerCleanTest.class); //default constructor is private Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP"); field.setAccessible(true); MethodHandles.Lookup trustedLookup = (MethodHandles.Lookup) field .get(null); MethodHandle mh = trustedLookup.findConstructor(InnerClass.class, type); mh.invoke(this); } @Test public void testInnerClassMethod() throws Throwable { InnerClass sut = new InnerClass(); MethodType type = MethodType.methodType(void.class); MethodHandle mh = lookup.findVirtual(InnerClass.class, "foo", type); mh.invoke(sut); }
}
如何通过MethodHandles.lookup()获取所有声明的方法? 如何获取所有声明的字段?
将java.lang.invoke视为反射(java.lang.reflect)的(快速执行)扩展-即“ invoke”类依赖于“ reflection”类。
java.lang.Class<?> someClass = ...; // obtain a Class somehow // Returns all constructors/methods/fields declared in class, // whether public/protected/package/private, // but does NOT include definitions from any ancestors: java.lang.reflect.Constructor<?>[] declaredConstructors = someClass.getDeclaredConstructors(); java.lang.reflect.Method[] declaredMethods = someClass.getDeclaredMethods(); java.lang.reflect.Field[] declaredFields = someClass.getDeclaredFields(); // Returns all constructors/methods/fields declared as public members // in the class AND all ancestors: java.lang.reflect.Constructor<?>[] publicInheritedConstructors = someClass.getConstructors(); java.lang.reflect.Method[] publicInheritedMethods = someClass.getMethods(); java.lang.reflect.Field[] publicInheritedFields = someClass.getFields();
java.lang.invoke.MethodType mt; java.lang.invoke.MethodHandle mh; java.lang.invoke.MethodHandles.Lookup lookup = MethodHandles.lookup(); // process methods for (java.lang.reflect.Method method: declaredMethods) { mh = lookup.unreflect(method); // can call mh.invokeExact (requiring first parameter to be the class' // object instance upon which the method will be invoked, followed by // the methodparameter types, with an exact match parameter and return // types) or // mh.invoke/invokeWithArguments (requiring first parameter to be the // class' object instance upon which the method will be invoked, // followed by the method parameter types, with compatible conversions // performed on input/output types) } // process constructors for (java.lang.reflect.Constructor<?> constructor: declaredConstructors) { mh = lookup.unreflectConstructor(constructor); // can call mh.invokeExact or // mh.invoke/invokeWithArguments } // process field setters for (java.lang.reflect.Field field: declaredFields) { mh = lookup.unreflectSetter(field); // can call mh.invokeExact or // mh.invoke/invokeWithArguments } // process field getters for (java.lang.reflect.Field field: declaredFields) { mh = lookup.unreflectGetter(field); // can call mh.invokeExact or // mh.invoke/invokeWithArguments }
// If generics involved in method signature: Type[] paramTypes = method.getGenericParameterTypes(); Type returnType = method.getGenericReturnType(); // Note: if Class is non-static inner class, first parameter of // getGenericParameterTypes() is the enclosing class // If no generics involved in method signature: Class<?>[] paramTypes = declaredMethod.getParameterTypes(); Class<?> returnType = declaredMethod.getReturnType(); // Note: if Class is non-static inner class, first parameter of // getParameterTypes() is the enclosing class // Same method calls for declaredConstructor
int modifiers = method.getModifiers(); // same method for constructor/field
boolean isStatic = java.lang.Modifier.isStatic(modifiers);
MethodHandle.invoke(),MethodHandle.invokeExact()和MethodHandle.invokeWithArguments()之间有什么区别?
MethodHandle
Class
invokeExact
Object invokeExact(Object... args)
invoke
invokeWithArguments
Object invokeWithArguments(List<?> arguments)
对于使用MethodHandle API for Java devloper的教程,我将不胜感激。
不幸的是,那里没有太多东西。您可以尝试以下方法。希望我已经在上面给出了足够的信息:^)
[http://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandle.html ](http://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandle.html) [http://docs.oracle.com/javase/7/docs/api/java/lang/invoke /MethodHandles.Lookup.html ](http://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandles.Lookup.html) [http://www.java7developer.com/blog/?p=191 ](http://www.java7developer.com/blog/?p=191) [http://www.oraclejavamagazine- digital.com/javamagazine/20130102?pg=52&search_term=methodhandle&doc_id=-1#pg50 ](http://www.oraclejavamagazine- digital.com/javamagazine/20130102?pg=52&search_term=methodhandle&doc_id=-1#pg50) [http: //www.amazon.com/Well-Grounded-Java-Developer-techniques- programming/dp/1617290068](https://rads.stackoverflow.com/amzn/click/com/1617290068)