Following are the differences between anonymous inner class and lambda expression:
- Anonymous inner class is a class without name. Lambda expression is a function without name.
- Anonymous inner class can extend abstract and concrete class. Lambda expression can not extend abstract and concrete class.
//Example of anonymous class extending concrete class. class Test{ public void play() { System.out.println("hello"); } } public class TestMain { public static void main(String args[]) { Test t = new Test(){ }; t.play(); } } //Example of anonymous class extending abstract class. abstract class Test{ public abstract void play(); } public class TestMain { public static void main(String args[]) { Test t = new Test(){ @Override public void play() { System.out.println("Hello"); } }; t.play(); } } //Example of anonymous inner class implementing interface interface Test{ public abstract void play1(); public abstract void play2(); } public class TestMain { public static void main(String args[]) { Test t = new Test(){ @Override public void play1() { System.out.println("inside play1 method"); } @Override public void play2() { System.out.println("inside play2 method"); } }; t.play1(); t.play2(); } }
- Anonymous inner class can implement an interface which contains more than one abstract method. Lambda expression can implement an interface which contains only one abstract method. Such interfaces are also known as Functional interfaces.
- Inside anonymous inner class, we can declare instance variables. Inside lambda expression, we can’t declare instance variables. Any variable declared inside lambda expression will be treated as local variable.
- Since anonymous inner class is a class, so it can be instantiated. Since lambda expression is a function, so it can’t be instantiated.
- Inside anonymous inner class, ‘this’ refers to current inner class object. Inside lambda expression, ‘this’ refers to enclosing class object.
In the following code, ‘this’ refers to the current inner class object. So, when we print this.score, the output is 100.
interface Playable{ public void play(); } public class Test { int score = 0; public void testMethod() { Playable p = new Playable(){ int score = 100; public void play() { System.out.println("Play with score " + this.score); //Output is 100 } }; p.play(); } public static void main(String args[]) { Test t = new Test(); t.testMethod(); } } //Output is //Play with score 100
In the following code, ‘this’ refers to enclosing class object . So, when we print this.score, the output is 0.
interface Playable{ public void play(); } public class Test { int score = 0; public void testMethod() { Playable p = () -> { int score = 100; System.out.println("Play with score " + this.score); }; p.play(); } public static void main(String args[]) { Test t = new Test(); t.testMethod(); } } //Output is //Play with score 0
- Compiling anonymous inner class creates a separate .class file. For lambda expression, no separate .class file is generated.
- Memory is allocated whenever object is created for anonymous inner class. For lambda expression, a new object need not be allocated on every evaluation. If lambda expression body is same, then objects produced by different lambda expressions need not belong to different classes.