Why do I need a functional Interface to work with lambdas?

前端 未结 6 2095
故里飘歌
故里飘歌 2020-11-27 15:09

I think this question is already somewhere out there, but I wasn\'t able to find it.

I don\'t understand, why it\'s necessary to have a functional interface to work

相关标签:
6条回答
  • 2020-11-27 15:41

    You seem to be looking for anonymous classes. The following code works:

    public class Test {
    
        public static void main(String...args) {
            TestInterface i = new TestInterface() {
                public void hans() {
                    System.out.println("Hans");
                }
                public void hans(String a) {
                    System.out.println(a);
                }
            };
    
            i.hans();
            i.hans("Hello");
        }
    }
    
    public interface TestInterface {
        public void hans();
        public void hans(String a);
    }
    

    Lambda expressions are (mostly) a shorter way to write anonymous classes with only one method. (Likewise, anonymous classes are shorthand for inner classes that you only use in one place)

    0 讨论(0)
  • 2020-11-27 15:42

    When you write :

    TestInterface i = () -> System.out.println("Hans");
    

    You give an implementation to the void hans() method of the TestInterface.

    If you could assign a lambda expression to an interface having more than one abstract method (i.e. a non functional interface), the lambda expression could only implement one of the methods, leaving the other methods unimplemented.

    You can't solve it by assigning two lambda expressions having different signatures to the same variable (Just like you can't assign references of two objects to a single variable and expect that variable to refer to both objects at once).

    0 讨论(0)
  • 2020-11-27 15:42

    A lambda expression is nothing but a shortcut to defining an implementation of a functional interface. It is equivalent to an instance of a functional interface implementation.

    0 讨论(0)
  • 2020-11-27 15:46

    The most important reason why they must contain only one method, is that confusion is easily possible otherwise. If multiple methods were allowed in the interface, which method should a lambda pick if the argument lists are the same ?

    interface TestInterface {
        void first();
        void second(); // this is only distinguished from first() by method name
        String third(); // maybe you could say in this instance "well the return type is different"
        Object fourth(); // but a String is an Object, too !
    }
    
    void test() {
        // which method are you implementing, first or second ?
        TestInterface a = () -> System.out.println("Ido mein ado mein");
        // which method are you implementing, third or fourth ?
        TestInterface b = () -> "Ido mein ado mein";
    }
    
    0 讨论(0)
  • 2020-11-27 15:54

    Functional interface can only contain exactly one abstract method according to java specs.

    Surely lambda expression can be one-time used as your commented code does, but when it comes to passing lambda expression as parameter to mimic function callback, functional interface is a must because in that case the variable data type is the functional interface.

    For example, Runnable is a built-in functional interface:

    public interface Runnable() {
        public void run();
    }
    

    The usage can be demonstrated as below:

    public class LambdaTest {
        // data type of parameter 'task' is functional interface 'Runnable'
        static void doSeveralTimes(Runnable task, int repeat) {
            for (int i = 0; i < repeat; i++) {
                task.run();
            }
        }
    
        public static void main(String[] args) {
            // one-time lambda
            doSeveralTimes(() -> {
                System.out.println("one-time lambda");
            }, 3);
    
            // lambda as variable
            Runnable test;
            test = () -> {
                System.out.println("lambda as variable");
            };
            doSeveralTimes(test, 3);
        }
    }
    

    and the result is:

    one-time lambda
    one-time lambda
    one-time lambda
    lambda as variable
    lambda as variable
    lambda as variable
    
    0 讨论(0)
  • 2020-11-27 16:06

    You do not have to create a functional interface in order to create lambda function. The interface allow you to create instance for future function invocation.

    In your case you could use already existing interface Runable

    Runnable r = () -> System.out.println("Hans");

    and then call

    r.run();

    You can think of lambda -> as only short hand for:

    Runnable r = new Runnable() {
         void run() {
              System.out.println("Hans");`
         }
    }
    

    With lambda you do not need the anonymous class, that is created under the hood in above example.

    But this has some limitation, in order to figure out what method should be called interface used with lambdas must be SAM (Single Abstract Method). Then we have only one method.

    For more detailed explanation read:

    Introduction to Functional Interfaces – A Concept Recreated in Java 8

    0 讨论(0)
提交回复
热议问题