3

While converting Java 8 access private member with lambda? from concrete format to generic format I found another limitation :

To issue a complete symbolic type descriptor, the compiler must also determine the return type. This is based on a cast on the method invocation expression, if there is one, or else Object if the invocation is an expression or else void if the invocation is a statement.

I am curious if there is a way to overcome this?

UPDATE: Working Example per Holger

Community
  • 1
  • 1
Andrei Pozolotin
  • 897
  • 3
  • 14
  • 21
  • 3
    Sure. Just use `invoke` rather than `invokeExact`. – Holger Jan 28 '15 at 18:57
  • Yes, it works, thank you @Holger. Does `invoke` vs `invokeExact` introduce boxing/unboxing or performance **penalty**? – Andrei Pozolotin Jan 28 '15 at 20:50
  • 1
    That obviously depends on the *required* conversions, e.g. converting `ToIntFunction` to `Object` does not require any boxing. Since you are using the `MethodHandle` exactly one time it doesn’t make sense to think about performance; even `invokeExact` will be rather slow (compared to an ordinary method invocation) for a particular handle. Only when you are going to invoke *the same* method handle very often, you may consider using `asType` once so you can use `invokeExact` multiple times afterwards, like described [here](http://stackoverflow.com/a/22321671/2711488) – Holger Jan 29 '15 at 08:57
  • 1
    Maybe I should emphasize that `invoke` is *signature-polymorphic* just like `invokeExact`, hence doesn’t require boxing or varargs handling like, e.g. `invokeWithArguments`. The difference is that `invoke` *allows* conversions and will do boxing/unboxing *if required* while `invokeExact` requires an exact match of the invoke type signature and the handle’s type signature. – Holger Jan 29 '15 at 09:03
  • In other words: once LambdaMetafactory has [produced the lambda](https://gist.github.com/Andrei-Pozolotin/6be08c431511c4813f63#file-privatetargetlambdaworking-java-L91), there will be no performance/boxing penalty (except for 1 level of indirection) during the [lambda usage](https://gist.github.com/Andrei-Pozolotin/6be08c431511c4813f63#file-privatetargetlambdaworking-java-L141), am I correct? @Holger please enter the answer, so I can mark this complete. – Andrei Pozolotin Jan 29 '15 at 13:58
  • Just to clarify: I want to make sure that whatever approach `invoke` or `invokeExact` is used with `LambdaMetafactory` to construct the lambda instance, it will not affect the resulting lambada internals in such a way that it will introduce unexpected boxing or performance penalty inside the lambda. – Andrei Pozolotin Jan 29 '15 at 15:19

1 Answers1

4

You can use invoke instead of invokeExact if your compile-time invocation signature does not match the invokedType parameter you have passed to the LambdaMetafactory. It will perform required conversions.

There is no performance penalty regarding the actual invocation of the lambda instance’s method. The decision how the generated lambda will work is made by the LambdaMetafactory before the CallSite encapsulating the MethodHandle is returned. Hence, the way you invoke it to construct the lambda instance does not influence the result.

Holger
  • 285,553
  • 42
  • 434
  • 765