专注Java教育14年 全国咨询/投诉热线:444-1124-454
赢咖4LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Java8新特性以及原因,入门学习

Java8新特性以及原因,入门学习

更新时间:2020-09-11 15:28:59 来源:赢咖4 浏览771次


一、接口的默认方法


Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用defau·t关键字即可,这个特征又叫做扩展方法,示例如下:

interface Formula {
 double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); }}

Formula接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用。

Formula formula = new Formula() {
 @Override public double calculate(int a) { return sqrt(a * 100); }};formula.calculate(100); // 100.0formula.sqrt(16); // 4.0


文中的formula被实现为一个匿名类的实例,该代码非常容易理解,6行代码实现了计算 sqrt(a * 100)。在下一节中,我们将会看到实现单方法接口的更简单的做法。


译者注: 在Java中只有单继承,如果要让一个类赋予新的特性,通常是使用接口来实现,在C++中支持多继承,允许一个子类同时具有多个父类的接口与功能,在其他语言中,让一个类同时具有其他的可复用代码的方法叫做mixin。新的Java 8 的这个特新在编译器实现的角度上来说更加接近Scala的trait。 在C#中也有名为扩展方法的概念,允许给已存在的类型扩展方法,和Java 8的这个在语义上有差别。


二、Lambda表达式


首先看看在老版本的Java中是如何排列字符串的:

List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() { @Override public int compare(String a, String b) { return b.compareTo(a); }});


只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。


在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:

Collections.sort(names, (String a, String b) -> {
 return b.compareTo(a);});


看到了吧,代码变得更段且更具有可读性,但是实际上还可以写得更短:

Collections.sort(names, (String a, String b) -> b.compareTo(a));


对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字,但是你还可以写得更短点:

Collections.sort(names, (a, b) -> b.compareTo(a));


Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。接下来我们看看lambda表达式还能作出什么更方便的东西来


三、函数式接口


Lambda表达式是如何在java的类型系统中表示的呢?每一个·ambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的·ambda表达式都会被匹配到这个抽象方法。因为默认方法不算抽象方法,所以你也可以给你的函数式接口添加默认方法。


我们可以将·ambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 Functiona·Interface注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。

@FunctionalInterface

interface Converter<F, T> { T convert(F from);}Converter<String, Integer> converter = (from) -> Integer.valueOf(from);Integer converted = converter.convert("123");System.out.println(converted); // 123


需要注意如果@FunctionalInterface如果没有指定,上面的代码也是对的。


译者注 将lambda表达式映射到一个单方法的接口上,这种做法在Java 8之前就有别的语言实现,比如Rhino JavaScript解释器,如果一个函数参数接收一个单方法的接口而你传递的是一个function,Rhino 解释器会自动做一个单接口的实例到function的适配器,典型的应用场景有 org.w3c.dom.events.EventTarget 的addEventListener 第二个参数 EventListener。


四、方法与构造函数引用


前一节中的代码还可以通过静态方法引用来表示:


Converter<String, Integer> converter = Integer::valueOf;

Integer converted = converter.convert("123");System.out.println(converted); // 123


Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,上面的代码展示了如何引用一个静态方法,我们也可以引用一个对象的方法:


 converter = something::startsWith;

String converted = converter.convert("Java");System.out.println(converted); // "J"


接下来看看构造函数是如何使用::关键字来引用的,首先我们定义一个包含多个构造函数的简单类:


class Person {

 String firstName; String lastName; Person() {} Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }}


接下来我们指定一个用来创建Person对象的对象工厂接口:


interface PersonFactory<P extends Person> {

 P create(String firstName, String lastName);}


这里我们使用构造函数引用来将他们关联起来,而不是实现一个完整的工厂:


PersonFactory<Person> personFactory = Person::new;

Person person = personFactory.create("Peter", "Parker");


我们只需要使用 Person::new 来获取Person类构造函数的引用,Java编译器会自动根据PersonFactory.create方法的签名来选择合适的构造函数。


Java8新特性以及原因,入门学习


以上就是赢咖4java培训机构的小编针对“Java8新特性以及原因,入门学习”的内容进行的回答,希望对大家有所帮助,如有疑问,请在线咨询,有专业老师随时为你服务。


提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>