Java 8出来有很长一段时间了,由于之前一直在搞Ruby都没时间好好学习下,趁着有空整理一下
http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
这里我们主要看编程语言相关的新特性:
Lambda表达式:
现在的匿名类有一个问题就是,当一个匿名类的实现非常简单,如一个接口只包含了唯一一个抽象方法,它的匿名类实现在解析的时候是笨重的且不清晰的。在这种情况下,我们通常会尝试将功能的实现当做另一个方法的参数传入,比如swing中当点击一个按钮,需要做的处理动作。Lambda表达式允许你这么做,将功能作为方法参数或者将代码作为数据。这个特性是属于函数式编程的特性,将一个代码块作为参数传入,如果学习过ruby的哈应该很好理解,与ruby的lambda表达式很类似。下面看一下官方给出的例子(由于例子太长,只展示重要部分,有兴趣可以自己去上面的地址看):
没有用Lambda表达式之前:
printPersons( roster, new CheckPerson() { public boolean test(Person p) { return p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25; } } );
用了之后:
printPersons( roster, (Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25);
可以看出用了Lambda之后字需要给出方法实现的代码即可,简洁了不少,代码嵌套也少了两层,如果实现代码有多行时,需要在 ->后面使用{}同时最后必须有return,同时参数的类型也可以省略,Java编译器可以根据方法定义自动推导出参数类型。
接口的默认方法:
Java 8 允许在接口中定义非抽象的方法,需要用关键字default,叫做接口的默认方法或者扩展方法,这种方法可以定义多个。
具体代码如下:
public interface Parser { String getResult(String info); default String notKnow() { return "Sorry I do‘t know!"; } default String anotherOne() { return "another one"; } }
public class AgeParser implements Parser { @Override public String getResult(String info) { if (info.matches("How old are you")) { return "I‘m 23"; } else { return notKnow(); } } public static void main(String[] args) { AgeParser parser = new AgeParser(); System.out.println(parser.getResult("How old are you")); System.out.println(parser.getResult("You do‘t know")); System.out.println(parser.anotherOne()); } }
默认方法在接口的实现类中可以直接使用不需要重写,当然也是可以在实现类中重写这个方法的,同时,如果其他的接口继承了这个接口,那么默认方法也会被继承,同时可以在接口中重写默认方法。
函数式接口:
在上面Lambda表达式中,曾提出过一个接口只包含了唯一一个抽象方法(可以同时包含多个默认方法),这个接口被叫做函数式接口,也只有函数式接口才能使用Lambda表达式创建其对应的匿名内部类的实例,同时为了确保接口一定满足函数式接口的要求,可以在接口申明的上面加上@FunctionalInterface注解,如果不满足要求,如抽象方法多余一个,就会编译不过。