A cheat sheet is all that is needed to start using Java Lambdas. But here I will start with the design changes done in Java8 in order to accommodate Lambdas.
Most of the interfaces in the JDK have only method. (Comparator, Runnable, Callable, etc) These are Single Abstract Method interfaces. These SAM concepts are recreated in Java8 using Functional Interfaces. Since a lambda function can only provide implementation for one method, it is mandatory for your functional interface to have ONLY ONE interface
Most of the interfaces in the JDK have only method. (Comparator, Runnable, Callable, etc) These are Single Abstract Method interfaces. These SAM concepts are recreated in Java8 using Functional Interfaces. Since a lambda function can only provide implementation for one method, it is mandatory for your functional interface to have ONLY ONE interface
Functional Interface
Interface with only one abstract method.
Methods from the Object class do not count. i.e. The interface can also declare the abstract methods from the java.lang.Object class, but still the interface can be called as a Functional Interface. Example
@FunctionalInterface public interface SimpleFunctionalInterface { public void doWork(); public boolean equals(Object o); }
It can also have
- static methods
- default methods
Note that the @FunctionalInterface is optional. It is just for convenience - the compiler can warn if it is not really a functional interface.
So what is the type of lambda expression? - Functional Interface
Is lambda expression an object? Well, it can be moved around like an object. An anonymous class is created with new. So I am explicitly asking JVM to create a new object (which is an overhead). but when I ask for a lamba, it is still recorded as an object in the JVM. But it is an object of a new kind in java8 - an object without an identity. I know this sounds complex. I will have a separate write-up on this. For now, the answer is no.
Default methods
In order to introduce lambda to Java 8, I need to add a forEach method to Iterable interface. Which will result in compilation error since all the classes that extends Iterable should provide an implementation for forEach. So I will be breaking the backward compatibility.
Hence the default methods. A new Java8 concept to change the old interfaces without breaking the existing implementations. It provides flexibility to allow interface define implementation which will use as default in the situation where a concrete class fails to provide an implementation for that method. Meaning, they can be overridden.
So what happens when the classes is implementing 2 interfaces with same default method signatures?
public interface InterfaceA { default void defaultMethod(){ System.out.println("Interface A default method"); } } public interface InterfaceB { default void defaultMethod(){ System.out.println("Interface B default method"); } } public class Impl implements InterfaceA, InterfaceB { }
So in these cases, to avoid compilation error, you have to provide your own implementation.
You can even choose to call either of the default methods like this:
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
Summary:
When we extend an interface that contains a default method, we can perform following,
- Override the default method similar to other methods we override in subclass..
- Not override the default method and will inherit the default method.
- Redeclare default method as abstract, which force subclass to override it.
Static Methods
The static methods in interfaces are good for providing utility methods.Eg : isEquals in java.util.function.Predicate & identity in java.util.function.FunctionWe can’t define interface static method for Object class methods, we will get compiler erroras “This static method cannot hide the instance method from Object”. This is becauseit’s not allowed in java, since Object is the base class for all the classes and we can’t haveone class level static method and another instance method with same signature.
These cannot be not overriden. if you think about it, it makes sense. Say I am providing a isNullutility in my interface so that the implementations do it right, then I will prevent thatto be overriddenNow let us talk about the inheritance part a bit more. How about static methods in class?public class SuperClass { public static void foo() { System.out.println("super class static"); } } public class SubClass extends SuperClass{ public static void foo() { System.out.println("sub class foo"); } } public class App { public static void main(String[] args) { SuperClass.foo(); SubClass.foo(); } }This would have printed :super class static sub class fooWhat if there is no foo() in SubClasspublic class SubClass extends SuperClass{ }It still works :super class static super class staticNow let us talk about static methods in interfacepublic interface SuperInterface { public static void foo() { System.out.println("super interface static"); } } public interface SubInterface extends SuperInterface{ public static void foo() { System.out.println("sub interface static"); } } public class App { public static void main(String[] args) { SuperInterface.foo(); SubInterface.foo(); } }Prints :super interface static sub interface staticWhat if there is not foo in SubInterface?public interface SubInterface extends SuperInterface{ }public class App { public static void main(String[] args) { SuperInterface.foo(); SubInterface.foo(); -> compilation error } }
Similarly, the following will work fine. Both class and interface can have static methods with same names, and neither overrides otherpublic class SomeClass implements SuperInterface{ public static void foo() { SuperInterface.foo(); } }public class App { public static void main(String[] args) { SomeClass.foo(); } }but the moment you remove foo from SomeClass, it will result in compilation errorpublic class SomeClass implements SuperInterface{ } public class App { public static void main(String[] args) { SomeClass.foo(); -> compilation error } }
So why default can be inherited and static cannot? These are my favorite answer from stackoverflow.1) A static method is a method that's associated with the class in which it's defined, rather than with any object created from that class. Every instance of the class shares the static methods of the class. Java 8 also lets static methods be defined in interfaces where they can assist default methods.When you implement an interface that contains a static method, the static method is still part of the interface and not part of the implementing class. For this reason, you cannot prefix the method with the class name. Instead, you must prefix the method with the interface name2) Static methods in interfaces could create a diamond of death if they were being inherited. So, calling a static method from the appropriate interface is good enough compared to the risk of calling it from a concrete class that may implement multiple interfaces that contain static methods of the same name.Why are static methods any different?Static methods are just functions unrelated to the objects. Instead of placing them in utility abstract classes (like calling Collections.sort() ) we move those functions (static methods) to their appropriate interfaces. They could be bound to the inherited objects like the default methods do, but that is not their job. Static methods provide functionality which is unrelated to the instances of the class.Example:interface Floatable { default void float() { // implementation } static boolean checkIfItCanFloat(Object fl) { // some physics here } } class Duck implements Floatable { }
So, the point is that a Duck may float but the function that checks if an Object really floats is not something that a Duck can do. It is an irrelevant functionallity that we could pass to our Floatable interface instead of having it sit inside some utility class.References :
- https://dzone.com/articles/interface-default-methods-java
- https://stackoverflow.com/questions/25169175/why-are-class-static-methods-inherited-but-not-interface-static-methods
- https://stackoverflow.com/questions/27833168/difference-between-static-and-default-methods-in-interfacE
No comments:
Post a Comment