我如何通过获得所有声明的方法MethodHandles.lookup()
?如何获取所有声明的字段?
有什么区别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
声明该方法的实例。在该类的实例上调用该方法(对于静态方法,则在Class本身上)。如果Class
s是非静态内部类,则第二个参数是封闭/声明类的实例。后续参数依次是方法签名参数。invokeExact
不会对输入参数进行自动兼容的类型转换。它要求参数值(或参数表达式)是与方法签名完全匹配的类型,每个参数作为单独的参数提供,或者所有参数作为数组一起提供(签名:)Object invokeExact(Object... args)
。 invoke
要求参数值(或参数表达式)类型兼容以匹配方法签名-执行自动类型转换,每个参数作为单独的参数提供,或所有参数作为数组一起提供(签名:Object invoke(Object .. 。args)) 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)
问题内容: 我今天发现了JPA 2.0 Criteria API,并想学习它。只是通过一些例子,尝试动手。我的桌上有水果列: ID, 名称, 颜色, 尺寸, 味道。 常规的东西: 如何使用条件构建以下查询: 即如何: 同样,在获取实际数据之前先获取结果计数总是更好的选择。我如何首先获取结果计数? 还有什么地方可以通过几种不同类型的SQL查询获得有关“条件”的更多示例? 问题答案: 首先,您要对实体
问题内容: 我是一名新的golang开发人员,我想知道为什么需要在项目的根目录设置环境变量。 如果我同时从事多个项目,则每次都需要重新设置环境变量以指向不同的位置。 在我的设置中,我已设置为。这是我所有golang项目的通用目录。 只是为了澄清:将项目数据放入 如果(据我所知)全部用于安装第三方库,那么为我所有的项目提供一个目录并不安全,因此所有必需的第三方库都安装在同一lib目录中,并且每当我在
在开始学习Keras之前,我们希望传递一些关于Keras,关于深度学习的基本概念和技术,我们建议新手在使用Keras之前浏览一下本页面提到的内容,这将减少你学习中的困惑 符号计算 Keras的底层库使用Theano或TensorFlow,这两个库也称为Keras的后端。无论是Theano还是TensorFlow,都是一个“符号主义”的库。 因此,这也使得Keras的编程与传统的Python代码有所
在开始学习Keras之前,我们希望传递一些关于Keras,关于深度学习的基本概念和技术,我们建议新手在使用Keras之前浏览一下本页面提到的内容,这将减少你学习中的困惑 符号计算 Keras的底层库使用Theano或TensorFlow,这两个库也称为Keras的后端。无论是Theano还是TensorFlow,都是一个“符号式”的库。 因此,这也使得Keras的编程与传统的Python代码有所差
各位大佬,我想问一下在开源项目Answer中的几个问题 answer开源项目是否支持LDAP answer开源项目是否支持webhook
本文向大家介绍一些基本的WordPress插件,包括了一些基本的WordPress插件的使用技巧和注意事项,需要的朋友参考一下 我知道您在想什么,但这不只是另一篇WordPress插件博客文章。每隔几周我会被问到我会推荐什么WordPress插件,而我总是总是从头到尾给出一些不连贯的列表。因此,我没有做这件事,我想记下我经常使用的插件是一个好主意,并建议其他插件使用。我还将尝试向我使用的插件添加任