functional interface java 8 vs anonymous inner class


  • Lambdas implement a functional interface.
  • Anonymous Inner Classes can extend a class or implement an interface with any number of methods.
  • Variables – Lambdas can only access final or effectively final.
  • State – Anonymous inner classes can use instance variables and thus can have state, lambdas cannot.
  • Scope – Lambdas can't define a variable with the same name as a variable in enclosing scope.
  • Compilation – Anonymous compiles to a class, while lambda is an invokedynamic instruction.

Anonymous Inner Classes (AICs)

  • The compiler generates a class file for each anonymous inner class.
    • For example – AnonymousInnerClass$1.class
  • Like all classes, it needs to be loaded and verified at startup.

Lambdas

  1. It has a simple, and easily readable syntax as compared to the anonymous inner class.
  2. It reduces the number of lines and boilerplate code in comparison to the anonymous inner class. In the code below, the highlighted blue syntax lines can be removed if we use Lambda.
  3. When we compile the class containing the anonymous inner class, it will create one extra class file for the anonymous  class.
The key to lambda implementation is the InvokeDynamic instruction, introduced in Java 7. This allows dynamic languages to bind to symbols at runtime.
A lambda works like this:
  • Generates invokedynamic call site and uses a lambdafactory to return the functional implementation.
  • Lambda converted to a method to be invoked by invokedynamic.
  • The method is stored in a class as a private static method.
  • There are two lambda types. Non-capturing lambdas only use fields inside their bodies, whereas capturing lambdas access fields outside their bodies.

1) Syntax
Lambda expressions looks neat as compared to Anonymous Inner Class (AIC)
public static void main(String[] args) {
    Runnable r = new Runnable() {
        @Override
        public void run() {
            System.out.println("in run");
        }
    };

    Thread t = new Thread(r);
    t.start(); 
}

//syntax of lambda expression 
public static void main(String[] args) {
    Runnable r = ()->{System.out.println("in run");};
    Thread t = new Thread(r);
    t.start();
}
2)Scope
An anonymous inner class is a class, which means that it has scope for variable defined inside the inner class.
  • Whereas,lambda expression is not a scope of its own, but is part of the enclosing scope.
Similar rule applies for super and this keyword when using inside anonymous inner class and lambda expression. In case of anonymous inner class this keyword refers to local scope and super keyword refers to the anonymous class’s super class. While in case of lambda expression this keyword refers to the object of the enclosing type and super will refer to the enclosing class’s super class.
//AIC
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int cnt = 5;    
                System.out.println("in run" + cnt);
            }
        };

        Thread t = new Thread(r);
        t.start();
    }

//Lambda
    public static void main(String[] args) {
        final int cnt = 0; 
        Runnable r = ()->{
            int cnt = 5; //compilation error
            System.out.println("in run"+cnt);};
        Thread t = new Thread(r);
        t.start();
    }
3) Performance
At runtime anonymous inner classes require class loading, memory allocation and object initialization and invocation of a non-static method while lambda expression is pure compile time activity and don’t incur extra cost during runtime. So performance of lambda expression is better as compare to anonymous inner classes

Comments