在Java8 函数式编程初识之Lambda表达式中讲了如果一个接口中仅有一个待实现的方法则它可以用Lambda代替.我们把这种接口叫做函数式接口,我们可以在该接口上写上@FunctionalInterface注解标明它是个函数式接口,但是无论标不标,它都会被Java识别为函数式接口
package cn.monoy.demos3;@FunctionalInterfacepublic interface FunctionalInterfaceDemo { public void doSomething(); @Override String toString(); }
所以在Java8中 Lambda 表达式的作用就是简化函数式接口,你会注意到,我在接口中写了一个Object类的方法toString(),这在Java8的函数式接口语法中是允许的,在用lambda 表达式的时候Java只会把表达式当成doSomething方法.也就是说在接口中声明Object类中的方法名不会影响这个接口成为一个函数式接口.
使用函数式接口的另一个好处就是可以用lambda表达式赋给一个接口声明的变量.
package cn.monoy.demos3;public class Main { public static void main(String[] args) {//创建线程 Runnable run = () -> { System.out.println("BlahBlahBlahBlah"); }; Thread thread = new Thread(run); thread.start();//我自己写的函数式接口 FunctionalInterfaceDemo fi = () -> { System.out.println("BlahBlahBlahBlah"); }; fi.doSomething(); } }
从如上代码可以看出,创建线程必须实现的Runnable接口也是一个函数式接口.我把同样的lambda表达式分别赋给了Runnable接口 和我自己写的FunctionalInterfaceDemo 接口,并不会发生什么错误.个人觉得这样的写法可以简化代码层级,使得可读性更好.当然,还是看个人喜好.
下面说说异常,在lambda表达式中的代码不可避免要遇到异常处理,如果在lambda表达式中遇到要处理异常.要么直接在表达式中try catch要么就在接口中声明的方法上面抛出,举例
package cn.monoy.demos3;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;public class Main { public static void main(String[] args) { FunctionalInterfaceDemo fi = () -> {//直接在代码块中处理 try { InputStream ins = new FileInputStream("test.txt"); } catch (FileNotFoundException e) { e.printStackTrace(); } }; fi.doSomething(); } }
我在接口中给doSomething 添加了throws 声明抛出异常,则在调用doSomething 时处理此异常
package cn.monoy.demos3;import java.io.FileInputStream;import java.io.InputStream;public class Main { public static void main(String[] args) { FunctionalInterfaceDemo fi = () -> { InputStream ins = new FileInputStream("test.txt"); }; //在调用时处理异常 也可以选择继续抛出 try { fi.doSomething(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
登录 | 立即注册