Java-8 – why can’t @ functionalinterface be applied to Sam abstract base classes

I just started learning camels. The first thing I saw was

context.addRoutes(new RouteBuilder() {
        public void configure() {
            from("file:data/in@R_841_2419@?noop=true").to("file:data/out@R_841_2419@");
        }
    });

I (reasonable IMHO) try to replace

context.addRoutes(()->from("file:data/in@R_841_2419@?noop=true").to("file:data/out@R_841_2419@"));

But this is invalid

During my mining, I found that Lambdas is applied to functional interfaces (which is considered as interface qualification), but @ functional interface annotation can only be applied to interfaces (fair enough). As far as I know, there is no equivalent annotation of abstract classes Routebuilder is of course an abstract class

Why is Lambdas limited to interfaces?

What is the essential difference between interfaces and classes that makes "functional classes" unsafe / unpredictable / unreasonable?

I can understand if there are some qualifiers, such as abstract methods, that must be made public, but I am disappointed to explain why the above is unreasonable

Solution

This is one of the most difficult and widely debated decisions in the JSR - 335 expert group On the one hand, single abstract method abstract class may be a reasonable conversion goal of lamb, which seems to be completely reasonable Moreover, if your mental model is "lamb is just a close anonymous class", then this theory is completely reasonable

However, if you pull this string for a while, you will realize that it delays a lot of complexity and constraints - for a few use cases

One of the worst things about procrastination is the meaning of the name in lambda, as a special case In the inner class, there is a very complex search rule ("comb search"), because the names in the inner class can refer to supertype members or can be obtained from the lexical environment (for example, many bugs and puzzle games revolve around this, not outer.this, in the inner class.) If we allow lambda transformation to abstract Sam classes, we will have two bad choices; Using the terrible name of the inner class to find complexity pollutes all Lambdas, or allows conversion to abstract class targets, but restricts access so that the lambda body cannot reference members of the base class (which will lead to its own confusion) The result rule we get is very clean: except for the lambda parameter forms, the names in the lambda body (including this is just a name) just mean what they mean outside the lambda body

Another problem in converting Lambdas to inner classes is the object identity and the consequent loss of VM optimization The inner class creation expression (for example, the new foo () {}) is guaranteed to have a unique object ID By not strongly identifying Lambdas, we can make many useful optimizations by releasing virtual machines, otherwise we can't Therefore, lambda linking and capturing are faster than anonymous classes, and we haven't applied a deeper optimization process yet

In addition, if you have a single abstract method abstract class and want to be able to create them using Lambdas, there is a simple path to do this - define a factory method with a function interface as a parameter (we added a factory method for ThreadLocal in Java 8 to do this)

The last nail in "Lambdas" is the convenient object syntax "After analyzing the existing code base and using single abstract method interfaces and abstract classes, the world view came. We found that only a small proportion are based on abstract classes. It seems foolish to confuse all lambs with complexity and performance problems, which can only benefit less than 1% of uses. So we made a" brave "decision, This use case has been reduced to achieve other 99% benefits

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>