posted 6 years ago
The internal structure of an object created by a lambda expression is incompatible with the internal structure of regular objects. Consider the following code:
Here's the decompiled bytecode:
You can see that the anonymous() method creates an instance of the anonymous Example$1 class, and then calls invokespecial on it to call the constructor.
In the case of a lambda expression, the method just returns the result of an InvokeDynamic call. InvokeDynamic returns something similar to a MethodHandle that is linked to a CallSite that is wrapped around a method, in this case the static lambda$lambda$0() method. If you don't understand it, don't worry. It's pretty magic, and Java doesn't really have anything in the language that uses InvokeDynamic, other than lambda expressions and default methods.
So why can't InvokeDynamic be used for abstract classes? Well, an abstract class is more than just a method handle. An abstract class may have fields, initializers and constructors. These are run with the invokespecial call that you see in the bytecode for anonymous().
One could ask, why then can't we use a lambda expression for abstract classes that don't have fields, don't have initializers and don't have constructors? Well, if an abstract class has no fields, initializers or constructors, then what is the point of it? You can just use an interface.