簡體   English   中英

Java 8 - 如何訪問封裝為lambda的對象和方法

[英]Java 8 - how to access object and method encapsulated as lambda

在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”?

這是可能的,因為捕獲的引用被轉換為runnable的字段(與所有匿名類一樣)。 但名稱不一致。

我通過測試發現你需要將myText設為非final ,否則它將被視為編譯時常量和內聯(並且不能作為字段訪問):

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

使用反射,無法獲取局部變量和方法參數值。 相反,您可以使用AOP攔截方法調用並檢查參數。

檢查是否需要某些內容作為下面的代碼,我已將runnable傳遞給inspect方法中的Thread對象。

    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) {
            Thread t = new Thread(runnable);
            t.start();

          }


        }

輸出將是:

怎么訪問這個?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM