7

Suppose I have an interface:

public interface Function {
    double function (double input);
}

Now, suppose I have created an instance of this interface somewhere in my main class,

Function f = (x) -> x;

How can I go about printing this function, in plain text? So, something a bit like this:

int f (double x) {return x}

Running a .toString on this Function prints something like Main$1@6d06d69c. How can I go about getting the java representation of this interface?

MazeOfEncryption
  • 365
  • 3
  • 13
  • 2
    It's not designed to allow you do do this. The longer answer is you can add instrumentation to decompile the code but that's a lot of work. – Peter Lawrey Apr 20 '18 at 18:09
  • Ah, that kinda stinks, thanks for the answer anyways! – MazeOfEncryption Apr 20 '18 at 18:10
  • 1
    I think it does as well. esp for debugging purposes, lambdas are a pain. – Peter Lawrey Apr 20 '18 at 18:13
  • 5
    Actually, you can never print the actual implementation of any method in Java, so why would the language allow you to do it in case of lambdas? – fps Apr 20 '18 at 18:30
  • 1
    For debug purposes, it could be very useful. Even if it weren't even in java itself, but an eclipse feature. – MazeOfEncryption Apr 20 '18 at 18:31
  • 1
    Yeah, I absolutely agree with you, it would be an awesome feature – fps Apr 20 '18 at 18:32
  • 1
    That can indeed be a pain in the back. Occasionally, I wrote sorts of "wrapper" methods like `Function f = wrap(g, "some description");` to have a sensible `toString` for the function (similarly, for predicates, as in [this class](https://github.com/javagl/Viewer/blob/master/viewer-core/src/main/java/de/javagl/viewer/Predicates.java) ). But having *anything else* than the `Main$1@6d06d69c` could make debugging *much* easier. So +1, even though I know there will be no "perfect" answer, maybe someone will post suggestions or workarounds. – Marco13 Apr 20 '18 at 18:43
  • What I wound up doing is implementing an optional "description" parameter into the constructor that uses the function, so that you can provide a short description of what the method does. – MazeOfEncryption Apr 20 '18 at 19:12

3 Answers3

2

Remember that the text of a function (otherwise known as "code") only exists when you write it. You compile this to bytecode which is then run on the Java Virtual Machine. At runtime, the original code which you wrote no longer exists and cannot be easily retrieved.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
1

Unfortunately, the answer (as of Java 9) is that there isn't a simple way to get the toString() method to give you a human-meaningful value for an arbitrary instance of a functional interface.

Here are a couple of alternatives that are applicable for some use-cases:

  • Instead of using a lambda, implement the interface using a class, and include an appropriate override for the toString() method.

  • Populate a Map<Function, String> with meaningful names for all of your Function instances.

It would be theoretically possible to build a library that can retrieve the ".class" file for (say) a lambda, analyse it, work out what the bytecodes do, and then produce an appropriate summary. But it would be difficult project.


It would be nice if there was a simple, clean solution to this. Maybe "someone" could suggest it as an RFE for a future version of Java.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
-1

You need to call the method in the interface explicitly by supplying a value of double, like below

Function f = (d) -> d;
System.out.print(f.function(2.0));