Well, if you can afford the extra overhead and security implications, you can use the Serializable functional interface and decode the serialized form of the method link instance to find the target, as shown in this answer or raised with this question and its answers again.
However, you must really rethink your software design. "Preventing infinite recursion" should not be fixed by decoding any parameter object, especially if your assumption is that this actual value of the argument is the calling object of your method. How would you never apply this weird relationship?
Even a simple code change, such as a reference to a method that delegates to another method, will violate your check. Here is a simple example showing subtle issues with your approach:
public class SimpleTest { public static void main(String... arg) { run(SimpleTest::process); } static void run(BiConsumer<Object,Object> c) { c.accept("foo", "bar"); } static void process(Object... arg) { Thread.dumpStack(); } }
When you run this program, it will print something like:
java.lang.Exception: Stack trace at java.lang.Thread.dumpStack(Thread.java:1329) at SimpleTest.process(SimpleTest.java:16) at SimpleTest.lambda$MR$main$process$a9318f35$1(SimpleTest.java:10) at SimpleTest$$Lambda$1/26852690.accept(Unknown Source) at SimpleTest.run(SimpleTest.java:13) at SimpleTest.main(SimpleTest.java:10)
showing that the method reference in the generated instance is not the expected SimpleTest::process , but instead SimpleTest::lambda$MR$main$process$a9318f35$1 , which ultimately calls process . The reason is that some operations (here varargs processing) are not performed by the generated interface instance, but instead by the synthetic method, like you wrote run((a,b)-> SimpleTest.process(a,b)) . The only difference is the name of the synthetic method.
You should not design software based on such a fragile introspection. If you want to avoid recursion, a simple ThreadLocal tag indicates whether you will already do the work in your specific method. But perhaps you should ask yourself why your API provokes infinite recursion in the first place; something seems fundamentally wrong ...
Holger Oct 30 '14 at 15:21 2014-10-30 15:21
source share