import java.util.function.*; class A {void a(){} } class B extends A {void b(){} } class C extends B {void c(){} } class App{ static C Foo(B b) { return null; } static Object Bar(B b) { return null; } static B Dummy(Object o) { return null; } static B Sam(C c) { c.c(); return null; } static void main(){ // Covariancia // Function<B, B> h1 = App::Foo; // aceita tipos derivados do tipo de retorno // Function<B, B> h2 = App::Bar; // erro de compilação: tipo de retorno incompatível h1.apply(null).a(); h1.apply(null).b(); // Contravariancia // Function<B, B> h3 = App::Dummy; // aceita tipos base do tipo do argumento // Function<B, B> h4 = App::Sam; // erro de compilação: C não e tipo base // h3.apply(new A()); // Erro de compilação -- A não é B h3.apply(new B()); // OK } }