On 09/07/2021 09:58, Konstantin Kolinko wrote:

Thanks Konstantin. This is good feedback.

пт, 9 июл. 2021 г. в 00:07, Mark Thomas <ma...@apache.org>:

<snip/>

      Add support for coercing LambdaExpression to any functional interface

The implementation for this turned out to be a lot simpler than I
initially thought. I can;t help be think I've missed something. Please
try and find ways to break this. If you do, feel free to add a disabled
out test case and I'll take a look.

Re: " if (obj instanceof LambdaExpression &&
type.getAnnotation(FunctionalInterface.class) != null) "

1. IIRC, using @FunctionalInterface annotation is a hint, not a requirement.

E.g. at 
https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html
"the compiler will treat any interface meeting the definition"...

E.g. lambdas can be used with legacy code that does not use that annotation.

I'll look into how easy it would be to handle the case where the annotation isn't present. I'm a little concerned about the overhead of determining if the functional interface definition is met but if that turns out to be an issue then some form of caching is likely to help.

2. Inheritance? If the annotation is applied not on this class or
interface, but on some of its parents.

Docs for "AnnotatedElement.getAnnotation(...)" - reading their
definition of "present", I think that that method goes up a hierarchy
of classes, but it does not go up a hierarchy of interfaces.
https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html

Example: a "SerializablePredicate" interface,
https://vaadin.com/api/framework/8.13.2/com/vaadin/server/SerializablePredicate.html
https://github.com/vaadin/framework/blob/master/server/src/main/java/com/vaadin/server/SerializablePredicate.java

The SerializablePredicate interface does not redeclare
@FunctionalInterface, but it is a functional interface.

I'll look into that too.

Re: "if (!Modifier.isAbstract(method.getModifiers())) { throw...."

3. While only one method is abstract, other methods may be called:
(a) methods defined by Object -  equals(), hashCode() and toString(),
(b) default methods defined in an interface.

The current code throws an ELException.

There is some sample code (though maybe not best) to deal with (a) at
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html

I do not know how people deal with (b). It may be that
InvocationHandler won't see those calls to default methods. (When I
studied java proxies, that feature did not exist yet.)

My thinking was that the proxy is only ever going to be used to map the LambdaExpression to the functional interface call. I couldn't see any way for any of those other methods to be called. Am I missing something?

I wonder how Java itself (a java compiler) deals with coercion of
lambdas to interfaces. Either it generates calls to some helper API,
or it just repeats the same boilerplate code over and over.

I'm not sure. I did look to see if there was anything in the public API around this I could use to help but didn't find anything.

Thanks,

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to