本文介绍了Java 8-如何访问封装为Lambda的对象和方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,您可以捕获"对象的方法调用"作为Runnable,如下例所示.

In Java you can "capture" a "method call on object" as a Runnable, as in belows example.

以后,如果可以访问此Runnable实例,则可以实际访问捕获的"对象和所调用方法的方法参数(如果可能,则可能需要通过反射来完成).

Later, having access to this instance of Runnable, is it possible to actually access the "captured" object and the method parameters of a method which is called (if possible this probably needs to be done via reflection).

例如:

class SomePrintingClass {
  public void print(String myText) {
    System.out.println(myText);

  }
}


public class HowToAccess {
  public static void main(String[] args) throws Exception {
    final String myText = "How to access this?";

    final SomePrintingClass printer = new SomePrintingClass();

    Runnable r = () -> printer.print(myText); // capture as Runnable

    inspect(r);
  }


  private static void inspect(Runnable runnable) {
    // I have reference only to runnable... can I access "printer" here

  }


}

在检查"方法中是否可以访问(可能通过反射)打印机"对象和作为参数传递的"myText"?

Is it possible in the "inspect" method to access (probably via reflection) "printer" object and "myText" which was passed as a parameter?

推荐答案

这是可能的,因为捕获的引用被转换为可运行字段(与所有匿名类一样).名称将不一致.

It is possible, because the captured references are translated into fields of the runnable (as with all anonymous classes). The names will be not be consistent however.

我通过测试发现您需要将myText设置为非final,否则它将被视为编译时间常数并内联(并且不能作为字段访问):

I found by testing that you need to make myText non-final, otherwise it will be seen as a compile time constant and in-lined (and will not be accessible as a field):

private static void inspect(Runnable runnable) throws Exception {       
    for(Field f : runnable.getClass().getDeclaredFields()) {
        f.setAccessible(true);
        System.out.println("name: " + f.getName());
        Object o = f.get(runnable);
        System.out.println("value: " + o);
        System.out.println("class: " + o.getClass());
        System.out.println();
    }
}

打印:

name: arg$1
value: test.SomePrintingClass@1fb3ebeb
class: class test.SomePrintingClass

name: arg$2
value: How to access this?
class: class java.lang.String

这篇关于Java 8-如何访问封装为Lambda的对象和方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 20:19