Showing posts with label anonymous class. Show all posts
Showing posts with label anonymous class. Show all posts

Tuesday, April 14, 2015

Functional Interfaces in Java 8

This post compliments the previous post where I have discussed about Lambda Expression, link. To unleash the power of lambda, a good understanding of functional interface is must. Let's briefly cover it:

Functional Interface

Functional Interfaces are those Interfaces in Java which has only one abstract method. Interfaces having single method (like Runnable, Callable, Comparable etc) existed in Java even before version 8. It's just that this new term was coined in context of Lamda Expression.

Functional interfaces are pre-condition for Lambda expression. Lambda expression allows you to provide the implementation of the method inline as an anonymous implementation of the interface.   Before Java 8, programmers used to provide implementation of functional interfaces using Anonymous class (which let you declare and instantiate the class at same time). Below is mostly commonly seen way to implement a Runnable task. 

  Runnable task = new Runnable(){
    public void run(){
        //implementation...bla bla.
  }
};

If interface is NOT functional, implementing the interface or providing anonymous implementation as shown above are two options. But if there is just one abstract method in the interface, Java 8 provides a more succinct and less verbose style to provide implementation. Java also introduces an optional annotation to mark an interface as functional. 


@FunctionalInterface
public interface MyFunctionalIf {
public String doSomething(String);

}

Annotation is used to indicate that the interface is intended to be functional interface. It's not mandatory to use the annotation but definitely a good practice. This annotation will also prevent you to accidentally add another method and break the functional contract of having just a single method. One important point to keep in mind is that default and static methods don't break the functional contract. 
Above interface can be used by implementing it in a concrete class or by providing ad-hoc implementation using anonymous class as shown for Runnable. 

Implementing Functional Interface using Lambdas

Functions were not first class citizen (before Java 8) and you need to have a handle of object to call/use method. Now let's see how lambda changes the implementation of functional interfaces:

Runnable lambdaTask = () -> { //implementation  };
lambdaTask.run();  //using lambda

MyFunctionalIf myFunctionalIf = (String message) ->  "hello "+ message;
myFunctionalIf.doSomething("Sid");   //using lambda

                                                                                   
Now, look how cleaner the functional implementation of the interfaces look. It's very concise, flexible and re-usable.

Please note that in second case, the curly brace as well as return clause is missing (both can be removed if there is only one line in the method body. Even type in argument is optional, so you can ignore String in above lambda expression. Notice that the name of the method is missing in lambda so it is also called as anonymous method

Default Method

Now interfaces can also provide a default methods. Obviously, functional interfaces can also have any number of default methods. You just need to add default keyword in method definition.

List<> interface adds a sort method so that you can sort a list by calling sort method on its instance instead of calling sort method from Collections utility class.

default void sort(Comparator<? super E> c) {
     //implementation 
}

In-built Functional Interfaces Added In Java 8

Imagine creating your own multiple functional interfaces. But, Java helps programmers by providing some reusable functional interfaces out of the box. 

Java designers have created a separate package for same, java.util.funtion.

So do check this package before creating your own functional interfaces. Chances are high that you will find one matching your needs.

---
keep coding !!!

Sunday, March 10, 2013

Inner classes in Java

Java provides a mechanism through which you can declare one class inside another class. It's known as Inner class or Nested class.

          class OuterClass{   //Enclosing class
                  class InnerClass{   } //Inner class
          }

So, here, we are dealing with class definition within another class. Inner class is a member of the enclosing class. Now obvious questions are : why do we need it ? when do we need to use it ? Is it same as composition ?

Let's understand different aspects of inner classes before addressing these questions:

case 1 : Normal/Plain Inner class (Nested class)

public class Outer{
        private String id;

        private class Inner{
            private String name;
            public void print(){
                System.out.format(" name :"+ this.name + " ;id: "+ id);
            }
        }
        public static void main(String[] args){
            Outer oc = new Outer();
            oc.id = "id1";
         
            Outer.Inner ic = oc.new Inner();
            ic.name = "rai";
          
            ic.print();  //prints name :rai ;id: id1
        }
    }
Above class is simplest possible way to see Inner class into action. Let's note few points about code :
  1. Normal classes (non-inner) cannot be made private or protected (can only have public and package access) but inner classes can even use private access modifier as shown above. Making inner class private enables you to completely hide details about its implementation.
  2. Inner class can only be accessed by its outer class.
  3. If you want to invoke inner class from a static method (like main method); you need to do as shown in main method i.e. create an instance of outer class first and then through it create inner class instance as OuterClass.InnerClass obj = <OuterClassInstance>.new InnerClass();
  4. Note, print method; you are able to directly access id attribute of outer class. This is possible because inner class instance is associated with an outer class instance (Outer.Inner ic = oc.new Inner();)

Above case, inner class instance is created inside static method of outer class; lets try to do the same inside a normal method of outer class:

public class Outer {
    public void setInner() {
        Inner i = new Inner();
        i.name = "rai";
        i.print();
    }

    private class Inner {
        private String name;

        public void print() {
            System.out.println(" name :" + name);
        }
    }

    public static void main(String[] args) {
        Outer oc = new Outer();
        oc.setInner();
    }
}
 So when you try to instantiate an inner class from the non-static method of outer class; you just need to create instance in normal way. This makes sense as setInner method is called by an instance of outer class; so you are creating inner class instance linked with an outer class instance.

Now, what if, Outer class as well as Inner class has same attribute named as id. How to access both inside inner class?

public class Outer {
    private String name;
   
    private class Inner {
        private String name;

        public void print() {
            System.out.println(" Inner name :" + this.name);
            System.out.println(" Outer Name :"+ Outer.this.name);
        }
    }
}

case 2 :  static Inner class or static Nested classes

Now let's analyze how a static inner class will behave and how can we access it? (need to brush up static keyword concepts? this tutorial). Static inner class is commonly referred to as static nested class. Objects of normal inner classes (non-static) implicitly keeps a reference to the object of the enclosing (Outer) class that created it. This is not true for static nested classes.

So when you don't need a connection between the inner class object and the outer class object, then you can declare the inner class as static. This means that you don't need an outer class object to instantiate inner class. And you can't access a non static outer class object from an object of a nested class.

public class Outer {
    private String name;
   
    private static class Inner {
        private String name;

        public void print() {
            System.out.println(" Inner name :" + name);
            //won't compile
            //System.out.println(" Outer Name :"+ Outer.this.name); 
        }
    }
   
    public static void main(String args){
        Inner i = new Inner();
        i.print();
    }
}
Static nested classes don't have any link with the outer class; so it is analogous to a static method.

case 3 :  Inner classes in methods/scopes

This is one of the trickiest and confusing aspect of inner classes; you can declare static classes inside body of a method or in a block. There are two possibilities :
  1. local classes : declare an inner class within body of method with name
  2. anonymous classes : declare an inner class within body of method without naming it
  local class : Below example shows a validation example. It checks if a string representation of number is even or odd.
public class Outer{
    public static void ifEven(String number) {
       final String message = "Even Test !";  //note it's final
       class EvenValidator {
            int val = 0;
            EvenValidator(String number){
                val = Integer.parseInt(number);
            }
            public boolean isEvenNumber() {
                System.out.println(" message : "+ message);
                return val % 2 ==0 ? Boolean.TRUE : Boolean.FALSE;
            }
            //static component not allowed
            /*public static void f(){
                System.out.println("hi");
            }*/
         }
        EvenValidator myNumber1 = new EvenValidator(number);
        System.out.print(myNumber1.isEvenNumber());
    }
    public static void main(String... args) {
        ifEven("123");
    }
}
  Output
      message : Even Test !
     false

Please note that local class can only access local variables and parameters of the enclosing block that are final (hence message is final). Also you can't declare or define any static members, as evident from commented static method f(). So local classes are like inner classes.

anonymous class : This takes local classes one step further by enabling you to declare and instantiate a class at the same time. So anonymous classes are like local classes except that they don't have a name.

interface Contents{
    int getValue();
}
public class Anonymous {  
    public Contents contents(final String message, int tmp){
        return new Contents(){
            private int i=10;
            public int getValue(){
                System.out.println(" message :"+ message);  //final is must
                return i;
            }
        };
    }
    public static void main(String[] args) {
        Anonymous a = new Anonymous();
        Contents c = a.contents("hi");
        System.out.println(" val :"+ c.getValue());
    }
}
Output:
 message :hi
 val :10

 Points which need to be noted :
  1. The semicolon at the end of the anonymous inner class marks  the end of the expression.
  2. If you're defining an anonymous inner class and want to use an object that's defined outside the anonymous inner class, then the compiler requires that the argument reference be final. This is why message is declared as final.
  3. You can't have a named constructor in an anonymous class as there's no name.
  4. tmp parameter doesn't need to be declared as final as it's not getting used anywhere in the code.

Let's see a more familiar example which uses Runnable interface to create threads.
public class Anonymous {  
    public Thread thread(){
        Runnable r = new Runnable(){
            public void run(){
                System.out.println("run");
            }
        };
        Thread t = new Thread(r);
        return t;
    }
    public static void main(String[] args) {
        Anonymous a = new Anonymous();
        Thread thread = a.thread();
        thread.start();
    }
}

case 4 :  Inner class inside interfaces

Normally you can't put any code inside an interface, but a nested/inner class can be part of an interface. Any class you put inside an interface is automatically public and static. So you can nest a class inside an interface when you want to create some common code to be used with all different implementations of that interface.
 interface ClassInInterface {
    class Dummy{ //static class
        public void sayHi(){
            System.out.println("Hi !");
        }
    }
}
public class ClassInsideInterface implements ClassInInterface{
    public static void main(String[] args){
        Dummy d = new Dummy();
        d.sayHi(); 
//prints Hi !
    }
}

.class files

Unlike normal classes which generates a single .class file; compiling a class which has inner classes generates separate class files. One class for outer class and one for each inner class. Below are two possibilities :
  1. If inner class has a name ( like in case 1 and case 2): Outer.class and Outer$Inner.class.
  2. If inner class is NOT named (i.e. anonymous inner class) : Anonymous.class and Anonymous$1.class 

why ?

  1. Inner class provides a view to the outer class, as it usually manipulates the outer class object that it was created within.
  2. Inner class can independently extend a class (or implement an interface). So it solves multiple inheritance problem of Java. Interfaces to an extent solve this problem by allowing you to implement multiple interfaces. But inner classes actually allow multiple implementation inheritance
  3. Is it same as composition ? big NO
---
do post your feedback !!!