java8 - interfaces, evolved
Post on 11-May-2015
230 Views
Preview:
DESCRIPTION
TRANSCRIPT
Interfaces, evolved
Interfaces, evolved
staticmethods
default methods
traitsfunctionalinterfaces
Static Methods
Static Methods
//No different from static methods from classes
public interface StaticFoo {
static void foo() {
System.out.println("Static implementation of foo");
}
}
Default Methods
Default MethodsPreviously, on Java 7
Default Methods
signature
class vision…
implem contract…
Java 7 – Interfaces
Default Methods
abstract class
utility class
staticmethods
copy / paste
Java 7 – Sharing Implementations
Default MethodsNow, in Java 8…
Default Methods
public interface Foo {
public default void foo() {
System.out.println("Default implementation of foo()");
}
}
Java 8 – Basic Syntax
Default Methods
public interface Itf {
//No implementation; will be overridden
public void foo();
//Default implementation; will be overriden
public default void bar() {
System.out.println("Itf -> bar() [DEFAULT]");
}
//Default implementation; will not be overriden
public default void baz() {
System.out.println("Itf -> baz() [DEFAULT]");
}
}
Java 8 – Call & Overload
Default Methods
public class Clazz implements Itf {
@Override
public void foo() {
System.out.println("Clazz -> foo()");
}
@Override
public void bar() {
System.out.println("Clazz -> bar()");
}
}
Java 8 – Call & Overload
Default Methods
public class Test {
public static void main(String[] args) {
Clazz clz = new Clazz();
clz.foo();
clz.bar();
clz.baz();
}
}
Java 8 – Call & Overload
Clazz -> foo()Clazz -> bar()Itf -> baz() [DEFAULT]
Default MethodsDiamond Inheritance
Default Methods
public interface InterfaceA {
public default void foo() {System.out.println("A -> foo()");}
}
public interface InterfaceB {
public default void foo() {System.out.println("B -> foo()");}
}
public class Test implements InterfaceA, InterfaceB {
//Whoops
}
Diamond Inheritance
error: class Test inherits unrelated defaults for foo() from types InterfaceA and InterfaceB
Default Methods
//Solution 1 : the class method has the priority
public class Test implements InterfaceA, InterfaceB {
@Override
public void foo() {
System.out.println("Test -> foo()");
}
}
Diamond Inheritance
Default Methods
//Solution 2 : we specify which method we want to call
public class Test implements InterfaceA, InterfaceB {
@Override
public void foo() {
InterfaceA.super.foo();
}
}
Diamond Inheritance
Default MethodsReflection & Proxies
Default Methods
public static void main(String[] args) {
Object proxy = Proxy.newProxyInstance(
Test.class.getClassLoader(),
new Class[]{InterfaceA.class, InterfaceB.class},
(targetProxy, targetMethod, targetMethodArgs) -> {
System.out.println(targetMethod.toGenericString());
return null;
});
((InterfaceA) proxy).foo();
((InterfaceB) proxy).foo();
}
Reflection & Proxies
public default void defaultmethods.InterfaceA.foo()public default void defaultmethods.InterfaceA.foo()
Default Methods
public static void main(String[] args) {
Object proxy = Proxy.newProxyInstance(
Test.class.getClassLoader(),
new Class[]{InterfaceA.class, InterfaceB.class},
(targetProxy, targetMethod, targetMethodArgs) -> {
System.out.println(targetMethod.toGenericString());
return null;
});
((InterfaceB) proxy).foo();
((InterfaceA) proxy).foo();
}
Reflection & Proxies
public default void defaultmethods.InterfaceA.foo()public default void defaultmethods.InterfaceA.foo()
Default Methods
public static void main(String[] args) {
Object proxy = Proxy.newProxyInstance(
Test.class.getClassLoader(),
new Class[]{InterfaceB.class, InterfaceA.class},
(targetProxy, targetMethod, targetMethodArgs) -> {
System.out.println(targetMethod.toGenericString());
return null;
});
((InterfaceA) proxy).foo();
((InterfaceB) proxy).foo();
}
Reflection & Proxies
public default void defaultmethods.InterfaceB.foo()public default void defaultmethods.InterfaceB.foo()
Default Methods
When two or more interfaces of a proxy class contain a method with the same name and parameter signature, the order of the proxy class's interfaces becomes significant. When such a duplicate method is invoked on a proxy instance, the Method object passed to the invocation handler will not necessarily be the one whose declaring class is assignable from the reference type of the interface that the proxy's method was invoked through. This limitation exists because the corresponding method implementation in the generated proxy class cannot determine which interface it was invoked through. Therefore, when a duplicate method is invoked on a proxy instance, the Method object for the method in the foremost interface that contains the method (either directly or inherited through a superinterface) in the proxy class's list of interfaces is passed to the invocation handler's invoke method, regardless of the reference type through which the method invocation occurred.
java.lang.reflect.Proxy, 2014
Reflection & Proxies
Traitsfunctional interfaces
VS
Traits
TraitsFrom what I understood, a trait encapsulates a single behavior.
Traits abstract method
derivedmethods
trait
…with their default implementation
Traits
public interface Orderable<T> extends Comparable<T> {
//everything relies on the implementation of compareTo
public default boolean isAfter(T other) {
return compareTo(other) > 0;
}
public default boolean isBefore(T other) {
return compareTo(other) < 0;
}
public default boolean isSameAs(T other) {
return compareTo(other) == 0;
}
}
Traits
public class Person implements Orderable<Person> {
private final String name;
public Person(String name) {
this.name = name;
}
@Override
public int compareTo(Person other) {
return name.compareTo(other.name);
}
}
Traits
public class Test {
public static void main(String[] args) {
Person tony = new Person("Tony Stark");
Person bruce = new Person("Dr. Robert Bruce Banner");
println("Tony compareto Bruce : " + tony.compareTo(bruce));
println("Tony > Bruce : " + tony.isAfter(bruce));
println("Tony < Bruce : " + tony.isBefore(bruce));
println("Tony == Bruce : " + tony.isSameAs(bruce));
}
}
Tony compareTo Bruce : 16Tony > Bruce : trueTony < Bruce : falseTony == Bruce : false
FunctionalInterfaces
FunctionalInterfacesone abstract / many defaults…
FunctionalInterfaces
@FunctionalInterface // optional
public interface Foo {
// 1 and only 1 abstract method
void foo();
// many defaults
default void bar() {…}
default void baz() {…}
…
}
one abstract / many defaults…
FunctionalInterfaces
@FunctionalInterface
public interface Foo {
void foo();
void bar(); // whoops, one too many
}
one abstract / many defaults…
error: Foo is not a functional interface multiple non-overriding abstract methods found in interface Foo1 error
FunctionalInterfaces
instance method
constructor
static method
lambda
…to pass them all
FunctionalInterfaces
public class Name {
private String firstName;
private String lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
}
Java 7
FunctionalInterfaces
public class NameParser<T> {
public T parse(String name, Creator<T> creator) {
String[] tokens = name.split(" ");
String firstName = tokens[0];
String lastName = tokens[1];
return creator.create(firstName, lastName);
}
}
Java 7
FunctionalInterfaces
public interface Creator<T> {
T create(String firstName, String lastName);
}Java 7
FunctionalInterfaces
public static void main(String[] args) {
NameParser<Name> parser = new NameParser();
Name res = parser.parse("Bruce Banner", new Creator<Name>() {
@Override
public Name create(String firstName, String lastName) {
return new Name(firstName, lastName);
}
});
}
Java 7
FunctionalInterfaces
@FunctionalInterface
public interface Creator<T> {
T create(String firstName, String lastName);
}
Java 8
FunctionalInterfaces
Name res = parser.parse("Bruce Banner", Name::new);Java 8
CO
NS
TR
UC
TO
R
FunctionalInterfaces
public class Factory {
public static Name createName(String firstName, String lastName) {
return new Name(firstName, lastName);
}
}
Name res = parser.parse("Bruce Banner", Factory::createName);
Java 8
ST
AT
IC M
ET
HO
D
FunctionalInterfaces
public class Factory {
public Name createName(String firstName, String lastName) {
return new Name(firstName, lastName);
}
}
Factory factory = new Factory();
Name res = parser.parse("Bruce Banner", factory::createName);
Java 8
INS
TA
NC
E M
ET
HO
D
FunctionalInterfaces
Name res = parser.parse("Bruce Banner", (s1, s2) -> new Name(s1, s2));Java 8
LA
MB
DA
EX
PR
ES
SIO
NS
FunctionalInterfacesjava.util.function
FunctionalInterfacesjava.util.function
Biblio
Biblio
CROISIER, Olivier. Java 8 : du neuf dans les interfaces !, 2014 http://thecodersbreakfast.net/index.php?post/2014/01/20/Java8-du-neuf-dans-les-interfaces
HORSTMANN, Cay S.. Java SE 8 for the Really Impatient. Addison-Wesley, 2014
SEIGNEURIN, Alexis. Java 8 – Interfaces fonctionnelles, 2014 http://blog.ippon.fr/2014/03/18/java-8-interfaces-fonctionnelles/
top related