我的问题与该线程中对LambdaMetafactory的显式使用密切相关,提供了一些很好的示例来使用LambdaMetafactory访问类的静态方法;但是,我想知道访问现有bean实例的非静态字段的等效代码是什么。似乎很难找到一个例子,我的每一次尝试都以无法正常工作的代码结束。
这是bean代码:
class SimpleBean {
private Object obj= "myCustomObject";
private static Object STATIC_OBJECT = "myCustomStaticObject";
public Object getObj() {
return obj;
}
public void setObj(final Object obj) {
this.obj = obj;
}
public static Object getStaticObj() {
return STATIC_OBJECT;
}
public static void setStaticObj(final Object obj) {
STATIC_OBJECT = obj;
}
}
在这里,一个工作单元测试成功访问了静态方法“ getStaticObj()”:
@Test
public void accessStaticMethod() throws Throwable
{
MethodHandles.Lookup caller = MethodHandles.lookup();
Method reflected = SimpleBean.class.getDeclaredMethod("getStaticObj");
MethodHandle methodHandle = caller.unreflect(reflected);
CallSite site = LambdaMetafactory.metafactory(caller,
"get",
MethodType.methodType(Supplier.class),
MethodType.methodType(Object.class),
methodHandle,
MethodType.methodType(Object.class));
MethodHandle factory = site.getTarget();
Supplier r = (Supplier) factory.invoke();
assertEquals( "myCustomStaticObject", r.get());
}
现在,我在这里尝试访问非静态的“ getObj()”方法失败:
@Test
public void accessNonStaticMethodTestOne() throws Throwable
{
SimpleBean simpleBeanInstance = new SimpleBean();
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodHandle methodHandle = caller.bind(simpleBeanInstance, "getObj", MethodType.methodType(Object.class));
assertEquals("myCustomObject", methodHandle.invoke());
// This test fails here with exception:
// java.lang.IllegalArgumentException: not a direct method handle
CallSite site = LambdaMetafactory.metafactory(caller,
"get",
MethodType.methodType(Supplier.class),
MethodType.methodType(Object.class),
methodHandle,
MethodType.methodType(Object.class));
MethodHandle factory = site.getTarget();
Supplier r = (Supplier) factory.invoke();
assertEquals( "myCustomObject", r.get());
}
@Test
public void accessNonStaticMethodTwo() throws Throwable
{
SimpleBean simpleBeanInstance = new SimpleBean();
MethodHandles.Lookup caller = MethodHandles.lookup();
Method reflected = SimpleBean.class.getDeclaredMethod("getObj");
MethodHandle methodHandle = caller.unreflect(reflected);
// This test fails here with exception:
// java.lang.invoke.LambdaConversionException: Incorrect number of parameters
CallSite site = LambdaMetafactory.metafactory(caller,
"get",
MethodType.methodType(Supplier.class),
MethodType.methodType(Object.class),
methodHandle,
MethodType.methodType(Object.class));
MethodHandle factory = site.getTarget();
factory = factory.bindTo(simpleBeanInstance);
Supplier r = (Supplier) factory.invoke();
assertEquals( "myCustomObject", r.get());
}
@Test
public void accessNonStaticMethodThree() throws Throwable
{
SimpleBean simpleBeanInstance = new SimpleBean();
MethodHandles.Lookup caller = MethodHandles.lookup();
Method reflected = SimpleBean.class.getDeclaredMethod("getObj");
MethodHandle methodHandle = caller.unreflect(reflected);
CallSite site = LambdaMetafactory.metafactory(caller,
"get",
MethodType.methodType(Supplier.class),
MethodType.methodType(Object.class, SimpleBean.class),
methodHandle,
MethodType.methodType(Object.class, SimpleBean.class));
MethodHandle factory = site.getTarget();
//This test fails here with exception:
// java.lang.IllegalArgumentException: no leading reference parameter: spike.LambdaBeanAccessAtRuntimeTest$SimpleBean@4459eb14
factory = factory.bindTo(simpleBeanInstance);
Supplier r = (Supplier) factory.invoke();
assertEquals( "myCustomObject", r.get());
}
每次尝试都会产生不同的负面结果,我真的希望有人能够帮助我至少完成一项测试。
如果要将值绑定到您的lamba,则必须将这些参数包括到invokedtype签名中:
SimpleBean simpleBeanInstance = new SimpleBean();
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodType getter=MethodType.methodType(Object.class);
MethodHandle target=caller.findVirtual(SimpleBean.class, "getObj", getter);
CallSite site = LambdaMetafactory.metafactory(caller,
"get", // include types of the values to bind:
MethodType.methodType(Supplier.class, SimpleBean.class),
getter, target, getter);
MethodHandle factory = site.getTarget();
factory = factory.bindTo(simpleBeanInstance);
Supplier r = (Supplier) factory.invoke();
assertEquals( "myCustomObject", r.get());
除了绑定值,您可以使用Function
以bean作为参数的a:
SimpleBean simpleBeanInstance = new SimpleBean();
MethodHandles.Lookup caller = MethodHandles.lookup();
MethodType getter=MethodType.methodType(Object.class);
MethodHandle target=caller.findVirtual(SimpleBean.class, "getObj", getter);
MethodType func=target.type();
CallSite site = LambdaMetafactory.metafactory(caller,
"apply",
MethodType.methodType(Function.class),
func.erase(), target, func);
MethodHandle factory = site.getTarget();
Function r = (Function)factory.invoke();
assertEquals( "myCustomObject", r.apply(simpleBeanInstance));
问题内容: 我有这段代码可以正常工作: 但是,如果方法是从不同的ClassLoader加载的类中的方法,则它将抛出: 如何将实例传递给? 问题答案: 如此回答所述,查找模式必须包含私有访问才能被接受。基本上,这意味着调用者 是 指定的类,因为它创建了特定的查找实例,或者查找类具有足够的信任关系,可以将查找对象传递给执行实际调用的代码(例如,在使用指向时隐含到特定的引导方法)。 从Java 9开始,
问题内容: 因此,我对“ setter”和“ getter”方法以及它们的有用与否有疑问。 假设我只是写了一个非常基本的程序,如下所示: 然后,假设我编写了另一个使用此“ Account”类的类,如下所示: 等等等 在编写时,我正在“ Account”类中更改变量“ name”的值。我可以按照自己喜欢的方式随意编写多次代码。但是,引起我注意的是,更好的做法是将“ Account”类中的变量设为私有
我有一节课: 在正常使用中,该类的行为与您预期的一样。方法和获取并设置复合列表。然而,我使用这个类作为一个对象,在使用JAX-WS构建的web服务中传递。当JAX-WS编译器看到这个类时,它会忽略和访问器,XSD中出现的唯一属性是。 在一天的大部分时间里,我的头撞在墙上,我决定尝试将私有方法的名称改为,突然间一切都如你所料。JAX-WS为属性创建了正确的模式。 似乎正在发生的事情是,JAX-WS看
问题内容: 在春季,bean的类可能没有公共构造函数,而只有私有构造函数吗?创建bean时会调用此私有构造函数吗?谢谢。 问题答案: 是的,Spring可以调用私有构造函数。如果找到具有正确参数的构造函数,无论可见性如何,它将使用反射将其构造函数设置为可访问的。
问题内容: 我有一台服务器,使用Java应用程序处理数据库和文件。当我启动我的应用程序时,我使用以下命令提供有关文件访问服务器的报告: 每次启动我的应用程序(重新启动计算机后),即使服务器已打开,我也会得到错误的响应。原因是因为我必须提供另一个用户的身份验证。我要做的是通过要求我输入用户名/密码的Windows访问服务器,然后我得到了有关对服务器文件访问的真实响应。 有没有办法 通过Java 而不
问题内容: 如果我有一个包私有的Java类(用“ class”声明,而不是“ public class”),那么将内部方法声明为public或protected或package- private确实没有区别,对吗?那么我应该使用哪个,或者什么时候该使用呢?我有点困惑。 问题答案: 如果我有一个包私有的Java类(用“ class”声明,而不是“ public class”),那么将内部方法声明为p