Java 8 - 如何访问封装为 lambda 的对象和方法

标签 java reflection lambda java-8

在 Java 中,您可以将“对象的方法调用”“捕获”为 Runnable,如下例所示。

稍后,访问 Runnable 的这个实例后,是否有可能实际访问“捕获的”对象和被调用方法的方法参数(如果可能,这可能需要通过反射来完成)。

例如:

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

  }


}

是否有可能在“inspect”方法中访问(可能通过反射)作为参数传递的“printer”对象和“myText”?

最佳答案

这是可能的,因为捕获的引用被翻译成可运行的字段(与所有匿名类一样)。但是,名称将不一致。

我通过测试发现你需要使 myText 成为非 final,否则它将被视为 compile time constant和内联(并且不能作为字段访问):

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 的对象和方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42298316/

相关文章:

c++ - 使用 lambda 函数签名的函数重载

java - 无法写入文件

java - 如何使用maven和jenkins从快照到发布

pointers - 扫描不工作

C# 注册嵌入式 Directshow 过滤器

java - 在 Java 中传递 lambda 表达式时方法不明确

java - Java中 'Model-View-Controller'模式的实现示例?

java - Tries 适用于没有字母表的语言吗?

c# - 使用 EntityFramework 和 .NET Native 时出现 PlatformNotSupportedException

c++ - 在几个可变的 lambda 中更改同一个 vector