Actually lambda expressions aren't "just an abbreviation to implement anonymous classes". The benefit of using lambda expression is that it has direct access to instance of this class (the class from which it was called), while anonymous class don't (it has its own this instance).
In other words, anonymous classes introduce a new scope. so that names are resolved from their superclasses and interfaces and can shadow names that occur in the lexically enclosing environment. For lambdas, all names are resolved lexically.
https://stackoverflow.com/a/22640484 And also
Lambda performance with Anonymous classes
When application is launched each class file must be loaded and verified.
Anonymous classes are processed by compiler as a new subtype for the given class or interface, so there will be generated a new class file for each.
Lambdas are different at bytecode generation, they are more efficient, used invokedynamic instruction that comes with JDK7.
For Lambdas this instruction is used to delay translate lambda expression in bytecode untill runtime. (instruction will be invoked for the first time only)
As result Lambda expression will becomes a static method(created at runtime). (There is a small difference with stateles and statefull cases, they are resolved via generated method arguments)
https://stackoverflow.com/a/33874965
For instance:
interface Supplier {
void foo();
}
class A {
private String name;
public void doSome() {
baz(() -> System.out.println(this.name));
}
private void baz(Supplier sup){
sup.foo();
}
}
or
class A {
private String name;
public void doSome() {
baz(new Supplier() {
void foo() {
System.out.println(A.this.name);
}
});
}
private void baz(Supplier sup){
sup.foo();
}
}
I recommend to read this: Java8 Lambdas vs Anonymous classes.
Answer from Andrew Kolesnyk on Stack OverflowActually lambda expressions aren't "just an abbreviation to implement anonymous classes". The benefit of using lambda expression is that it has direct access to instance of this class (the class from which it was called), while anonymous class don't (it has its own this instance).
In other words, anonymous classes introduce a new scope. so that names are resolved from their superclasses and interfaces and can shadow names that occur in the lexically enclosing environment. For lambdas, all names are resolved lexically.
https://stackoverflow.com/a/22640484 And also
Lambda performance with Anonymous classes
When application is launched each class file must be loaded and verified.
Anonymous classes are processed by compiler as a new subtype for the given class or interface, so there will be generated a new class file for each.
Lambdas are different at bytecode generation, they are more efficient, used invokedynamic instruction that comes with JDK7.
For Lambdas this instruction is used to delay translate lambda expression in bytecode untill runtime. (instruction will be invoked for the first time only)
As result Lambda expression will becomes a static method(created at runtime). (There is a small difference with stateles and statefull cases, they are resolved via generated method arguments)
https://stackoverflow.com/a/33874965
For instance:
interface Supplier {
void foo();
}
class A {
private String name;
public void doSome() {
baz(() -> System.out.println(this.name));
}
private void baz(Supplier sup){
sup.foo();
}
}
or
class A {
private String name;
public void doSome() {
baz(new Supplier() {
void foo() {
System.out.println(A.this.name);
}
});
}
private void baz(Supplier sup){
sup.foo();
}
}
I recommend to read this: Java8 Lambdas vs Anonymous classes.
The x is not recognized as a field from the Age interface. You have to either do a static import (import static Age.x) or specify where the x comes from:
Age oj1 = () -> System.out.print("Age is "+ Age.x);
An anonymous inner class (AIC) can be used to create a subclass of an abstract class or a concrete class. An AIC can also provide a concrete implementation of an interface, including the addition of state (fields). An instance of an AIC can be referred to using this in its method bodies, so further methods can be called on it, its state can be mutated over time, etc. None of these apply to lambdas.
I'd guess that the majority of uses of AICs were to provide stateless implementations of single functions and so can be replaced with lambda expressions, but there are other uses of AICs for which lambdas cannot be used. AICs are here to stay.
UPDATE
Another difference between AICs and lambda expressions is that AICs introduce a new scope. That is, names are resolved from the AIC's superclasses and interfaces and can shadow names that occur in the lexically enclosing environment. For lambdas, all names are resolved lexically.
Lambdas though a great feature, will only work with SAM types. That is, interfaces with only a single abstract method. It would fail as soon as your interface contains more than 1 abstract method. That is where anonymous classes will be useful.
So, no we cannot just ignore anonymous classes. And just FYI, your sort() method can be more simplified, by skipping the type declaration for p1 and p2:
Collections.sort(personList, (p1, p2) -> p1.firstName.compareTo(p2.firstName));
You can also use method reference here. Either you add a compareByFirstName() method in Person class, and use:
Collections.sort(personList, Person::compareByFirstName);
or, add a getter for firstName, directly get the Comparator from Comparator.comparing() method:
Collections.sort(personList, Comparator.comparing(Person::getFirstName));
tl;dr: while it's mostly syntactic sugar, that nicer syntax makes lots of things practical that used to end in endless, unreadable lines of braces and parentheses.
Well, it's actually the other way around as lambdas are much older than Java. Anonymous inner classes with a single method are (were) the closest Java came to lambdas. It's an approximation that was "good enough" for some time, but has a very nasty syntax.
On the surface, Java 8 lambdas seem to be not much more than syntactic sugar, but when you look below the surface, you see tons of interesting abstractions. For example the JVM spec treats a lambda quite differently from a "true" object, and while you can handle them as if they where objects, the JVM is not required to implement them as such.
But while all that technical trickery is interesting and relevant (since it allows future optimizations in the JVM!), the real benefit is "just" the syntactic sugar part.
What's easier to read:
myCollection.map(new Mapper<String,String>() {
public String map(String input) {
return new StringBuilder(input).reverse().toString();
}
});
or:
myCollection.map(element -> new StringBuilder(element).reverse().toString());
or (using a method handle instead of a lambda):
myCollection.map(String::toUpperCase);
The fact that you can finally express in a concise way which would previously be 5 lines of code (of which 3 are utterly boring) brings a real change of what is practical (but not of what is possible, granted).
For Java, yes, it's nothing more than a better way of creating an anonymous inner class. This is because of the fundamental decision in java that every bit of byte code has to live within a specific class, which cannot be changed now after decades of legacy code to consider.
However, that is not what lambda expressions really are about. In formalisms where they are native concepts rather than a jump-on-the-bandwagon contortion, lambdas are fundamental building blocks; both their syntax and people's attitude towards them are very different. The example of an anonymous recursive function created purely out of lambdas in Structure and Interpretation of Computer Programs is capable of changing your entire conception of computation. (However, I'm pretty certain that way of learning to program is just to esoteric ever to become a mainstream success story.)