java8入门(一) --λ表达式
2016-09-19 09:34
393 查看
先来看一个简单的接口,通过学生的学号获取姓名,假设接口是这样子的。
简单吧,现在如果我们要用getName,有几种方法呢,首先想到的应该是写一个类Student实现IStudent,或者用匿名内部类,又或者用java8的λ表达式。所以代码如下,
仔细对比一下匿名内部类和λ表达式,是不是觉得λ表达式就去掉了类的外壳,然后方法简写了一下呢?事实就是这样的,λ表达式就是接口里的唯一未实现方法,语法是这样子的,(参数列表),箭头->,函数体。然后只有一的时候可以省略,一个参数可以省略小括号,一句函数体可以省略大括号,哦,对了 一句函数体的话,return也可以省略。所以只有一的时候省略。
λ表达式究竟是个什么玩意呢? 刚刚说了是接口里的唯一未实现方法,这句话挺拗口的,我们来看看是怎么一回事。先看printName,λ表达式传进来,我们的方法是用了一个接口类IStudent来接收的,所以它是一个接口。实际上这样调用也是可以的。
然后它又是一个方法,那它怎么知道是接口的哪一个方法呢。实现类或者匿名内部类都可以通过方法名,参数类型之类的找出,而λ表达式又没方法名,参数类型也是没有的,这按传统的方法就没辙了。所以java8给了一个简单粗暴的办法,就找接口里面唯一没有实现的方法。所以如果接口里面有多个未实现方法,那就会编译报错了。比如在接口里随便加上
然后就会报 The target type of this expression must be a functional interface,所以为了无意间忘记了这个是λ表达式接口(或者叫函数式接口),推出了一个注解@FunctionalInterface,就是说这个接口只能有一个未实现方法,如果不是,就会提示出错的。
然而毕竟接口有时需要多个方法的,这下怎么办呢?别急,java8推出了一个default,就是在接口中也可以有具体的方法,而且这个方法在子类也是可以重写的。然后把接口改写如下就可以了。
想一下,java8的接口是不是要逆天了,哈哈,今天先说到这吧。
package help.mygod.java8; public interface IStudent { String getName(String id); }
简单吧,现在如果我们要用getName,有几种方法呢,首先想到的应该是写一个类Student实现IStudent,或者用匿名内部类,又或者用java8的λ表达式。所以代码如下,
package help.mygod.java8; public class Main { public static void main(String[] args) { // 1,实现接口 IStudent student = new Student(); printName(student, "007"); // 2,匿名内部类 printName(new IStudent() { @Override public String getName(String id) { if ("007".equals(id)) return "William"; else return "Moss"; } }, "007"); // 3,λ表达式 printName(id -> { if ("007".equals(id)) return "William"; else return "Moss"; }, "007"); } public static void printName(IStudent student, String id) { System.out.println(student.getName(id)); } }
仔细对比一下匿名内部类和λ表达式,是不是觉得λ表达式就去掉了类的外壳,然后方法简写了一下呢?事实就是这样的,λ表达式就是接口里的唯一未实现方法,语法是这样子的,(参数列表),箭头->,函数体。然后只有一的时候可以省略,一个参数可以省略小括号,一句函数体可以省略大括号,哦,对了 一句函数体的话,return也可以省略。所以只有一的时候省略。
λ表达式究竟是个什么玩意呢? 刚刚说了是接口里的唯一未实现方法,这句话挺拗口的,我们来看看是怎么一回事。先看printName,λ表达式传进来,我们的方法是用了一个接口类IStudent来接收的,所以它是一个接口。实际上这样调用也是可以的。
package help.mygod.java8; public class Main { public static void main(String[] args) { IStudent student = id -> { if ("007".equals(id)) return "William"; else return "Moss"; }; printName(student,"007"); } public static void printName(IStudent student, String id) { System.out.println(student.getName(id)); } }
然后它又是一个方法,那它怎么知道是接口的哪一个方法呢。实现类或者匿名内部类都可以通过方法名,参数类型之类的找出,而λ表达式又没方法名,参数类型也是没有的,这按传统的方法就没辙了。所以java8给了一个简单粗暴的办法,就找接口里面唯一没有实现的方法。所以如果接口里面有多个未实现方法,那就会编译报错了。比如在接口里随便加上
package help.mygod.java8; public interface IStudent { String getName(String id); void printName(); }
然后就会报 The target type of this expression must be a functional interface,所以为了无意间忘记了这个是λ表达式接口(或者叫函数式接口),推出了一个注解@FunctionalInterface,就是说这个接口只能有一个未实现方法,如果不是,就会提示出错的。
然而毕竟接口有时需要多个方法的,这下怎么办呢?别急,java8推出了一个default,就是在接口中也可以有具体的方法,而且这个方法在子类也是可以重写的。然后把接口改写如下就可以了。
package help.mygod.java8; @FunctionalInterface public interface IStudent { String getName(String id); default void printName(){ System.out.println("I student"); } }
想一下,java8的接口是不是要逆天了,哈哈,今天先说到这吧。
相关文章推荐
- Lua学习笔记之运算符和表达式
- Lua教程(三):表达式和语句
- Lua基础教程之赋值语句、表达式、流程控制、函数学习笔记
- Ruby中case表达式详解
- 浅谈C/C++ 语言中的表达式求值
- C++表达式new与delete知识详解
- 剖析C++中的常量表达式与省略号的相关作用
- 实例详解C#正则表达式
- C++利用链栈实现表达式求值
- C#编程自学之运算符和表达式
- 理解C#中的Lambda表达式
- JavaScript学习笔记整理_关于表达式和语句
- 深入理解逻辑表达式的用法 与或非的用法
- javascript属性访问表达式用法分析
- 老生常谈JavaScript 函数表达式
- JavaScript中:表达式和语句的区别[译]
- 详解JavaScript的表达式与运算符
- js 中的switch表达式使用示例
- js表达式计算器代码
- SQLite教程(六):表达式详解