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