在 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
non-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();
}
}
Prints:
name: arg$1
value: test.SomePrintingClass@1fb3ebeb
class: class test.SomePrintingClass
name: arg$2
value: How to access this?
class: class java.lang.String
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)