Java8 的一些新特性总结
目前Java8已经发布很多个版本了,对于Java8中的新特性虽然有各位大神进行jdk8的英文特性文档翻译,但都太官方化语言,对照几篇翻译本人对新特性文档做一下总结,以帮助我和各位不了解Java8新特性的Java工程师们对其进行了解,水平有限,有错误之处请各位不吝赐教。
接口的改善(接口的默认方法):
在Java8以前接口的作用主要是对实现接口的类进行规范的,在其中只能定义常量和抽象方法。
Java8中允许我们去定义一个非抽象方法,这个方法是一个静态方法 ,用default关键字来定义这个默认方法,同时这个特性也被称为扩展方法,代码如下。
interface Formula {
double calculate(int a);
Public default double sqrt(int a) {
return Math.sqrt(a);
}
}
实现Formula接口的类只需实现calculate方法,而sqrt方法已经在接口中实现,从而子类无需实现可直接调用,以下是一个匿名实现的代码。
Formula formula = new Formula() {
@Override
public double calculate(int a) {
return sqrt(a * 100);
}
};
formula.calculate(100); // 100.0
formula.sqrt(16); // 4.0
且在Java8的核心类库的接口中大量的默认方法也被添加,这在API手册中应该可以查到。
函数接口:
函数接口是Java8中引入的一个核心概念,既若一个接口只定义了唯一一个抽象方法,那么这个接口就成为一个函数接口,如线程接口java.lang.Runnable就是一个典型的函数接口,在Runnable接口中只有public abstract void run();方法这一个抽象方法。
abstract关键词为隐含的,只是为了表示此为一个函数式接口,并不一定需要。而且函数接口中可以定义任意多的默认方法,这完全由工程师自己决定。
新添加一个Annotation(注解)@FunctionalInterface,这个注解可以放在接口前,用来表示此接口是一个函数接口,此注解和@Override作用差不多,只声明使用意图,避免错误使用,并不会被编译。
Lambdas表达式:
Lambdas表达式为Java8提供更简洁和更具可读性的代码。
在Java8之前匿名内部类的创建代码常常会使得代码阅读性降低,如下是实现一个字符串的匿名内部类:
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);
}
});
这种代码对程序工程师们非常不友好的,尤其对于那些经验不丰富的人来说若在程序内有大量这种代码简直是一场灾难。
用Lambdas表达式可以简化这种匿名类的创建:
Collections.sort(names, (String a, String b) -> {
return b.compareTo(a);
});
显然这种使用Lambdas表达式的方式可以使代码阅读性更加的好,当然我们可以把以上代码写的更短,对于函数体只有一行的,可以去掉{}和return关键词:
Collections.sort(names, (String a, String b) -> b.compareTo(a));
但是也可以更加的短:
Collections.sort(names, (a, b) -> b.compareTo(a));
因为Java编译器可以自动推导出参数类型,所以可以不用再一次写类型。这里还有一些Lambdas表示式的列子,以帮助大家更好的理解Lambdas表达式。
左边是指定类型的参数列表,右边是return代码块:
(int a, int b)->{return x+y;}
左边是推导类型的参数列表,右边为返回值:
(x, y)->x+y
左边为单参数的推导列表,右边是返回值:
x->x*x
左边无参数(官方名称: "burger arrow"),右边一个返回值:
()->x
左边推导类型单一参数,右边无返回值代码块(void):
x -> { System.out.println(x); }
静态方法引用:
String::valueOf等价于x -> String.valueOf(x)
非静态方法引用:
Object::toString等价于x -> x.toString()
继承的函数引用:
x::toString等价于() -> x.toString()
构造函数引用:
ArrayList::new等价于() -> new ArrayList<>()
重载对Lambdas同样有效。一个lambda和给定的函数式接口在“外型”匹配的时候兼容。通过“外型”,我指向输入、输出的类型和声明检查异常。
两个例子:
Comparator<String> c = (a, b) -> Integer.compare(a.length(),b.length());
一个Comparator<String>的compare方法需要输入两个参数,然后返回一个int。这和lambda右侧的一致,因此这个任务是有效的。
Runnable r = () -> { System.out.println("Running!"); }
一个Runnable的run方法不需要参数也无返回值。这和lambda表达式右侧一致,所以任务有效。
在抽象方法的签名里的检查异常(如果存在)也很重要。如果函数式接口在它的签名里声明了异常,lambda只能抛出受检查异常。
捕获和非捕获的Lambda表达式:
当Lambda表达式访问一个定义在Lambda表达式体外的非静态变量或者对象时,这个Lambda表达式称为“捕获的”。比如,下面这个Lambda表达式捕捉了变量x:
int x = 5; return y -> x + y;
为了保证这个lambda表达式声明是正确的,被它捕获的变量必须是“有效final”的。所以要么它们需要用final修饰符号标记,要么保证它们在赋值后不能被改变。
从性能上一个非捕获的Lambda比捕获的Lambda通常更高效。
Lambda不提供的一些特性:
Non-final* 变量捕获 - 如果一个变量被赋予新的数值,它将不能被用于lambda之中。"final"关键字不是必需的,但变量必须是“有效final”的。
int count = 0;
List<String> strings = Arrays.asList("a", "b", "c");
strings.forEach(s -> {
count++; // 错误: 不能修改 count 的值
});
异常的透明度 - 如果一个检测的异常可能从lambda内部抛出,功能性的接口也必须声明检测异常可以被抛出。这种异常不会散布到其包含的方法。
控制流程 (break, early return) - 传统的继续方式有可能通过在lambda之内放置 "return;"来实现。但是,没有办法中断循环或者从lambda中通过包含方法的结果返回一个数值。
final String secret = "foo"; boolean containsSecret(Iterable<String> values) {
values.forEach(s -> { if (secret.equals(s)) {
??? // 想终止循环并返回 true, 但是不行 }
});
}
抽象类不能被Lamdba实例化 - 这样做引发的最常见的争论就是会增加阅读lambda的难度。以这种方式实例化一段抽象类将导致隐藏代码的执行:抽象类的构造方法。
以上是本人对其他一些翻译后的Java8文档的梳理总结,在总结过程中也发现翻译后的文档有诸多语义不明确的地方,对照原文进行理解,但限于本人英文能力有限,只对部分细枝末节的地方进行了修改,若大家有更好的理解还希望能多与大家交流进步。关于Java8中的新增和优化的API部分将另为进行梳理总结。
Java8 的一些新特性总结的更多相关文章
- Java基础学习总结(33)——Java8 十大新特性详解
Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...
- 【Java8新特性】一张图带你领略Java8有哪些新特性
写在前面 很多小伙伴留言说,冰河你能不能写一些关于Java8的文章呢,看书看不下去,看视频进度太慢.好吧,看到不少读者对Java8还是比较陌生的,那我就写一些关于Java8的文章吧,希望对大家有所帮助 ...
- 常见面试题:java8有什么新特性?
常见面试题:java8有什么新特性? 主要有以下这些新特性: lambda 表达式,经常配合函数式接口使用,可以有效减少代码量 Runnable 是一个函数式接口,下面展示了创建线程三种写法,显然最后 ...
- JAVA8 十大新特性详解
前言: Java8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章, 例如Playing with Java ...
- Java8 十大新特性详解(转)
本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...
- Java语言:JAVA8 十大新特性详解(zz)
关键词: Lambda表达式.函数式接口.方法与构造函数引用.接口的默认方法 原文地址: http://www.jb51.net/article/48304.htm 本教程将Java8的新特新逐一列出 ...
- Java8 的一些新特性的学习理解
近期在学习队列相关的一些知识,在学习过程中发现Iterable<T>接口中新增了两个新的方法,出于好奇,就想知道这是什么东东,干什么用的.俗话说:实践出真知,所以就有了以下反复的测试. 先 ...
- java8 十大新特性
这篇文章是对Java 8中即将到来的改进做一个面向开发者的综合性的总结,JDK的这一特性将会在2013年9月份发布. 在写这篇文章的时候,Java 8的开发工作仍然在紧张有序的进行中,语言特新和API ...
- java8的接口新特性(可以有方法体的接口)(转)
以前Java的接口中定义的方法不可以有方法体,这样试用起来,有时候听不方便的,当有多个类实现了想同的接口,接口中某一些方法的实现体可能都是一样的时候,这样无疑浪费了很多时间,在写重复的代码(或者说co ...
随机推荐
- Filter,Listener(转)
一.Filter的功能filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个reques ...
- callback回调函数理解 相当于this指针
1.callback函数在微软的官方手册中是这样定义callback函数的:“callback函数是由应用程序定义而由操作系统调用的函数”. 凡是由用户设计而却由windows系统调用的函数,统称 ...
- Java入门程序
JavaC.exe 编译器,编译.java文件 Java.exe 解释器,执行class文件 编译命令 javac HelloWorld.java 编译后 会产生同名的.class文件 javac编 ...
- C++闭包,一样很简单
引用百度上对闭包的定义:闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量).“闭包” 一词来源于以下两 ...
- delphi 中的函数指针 回调函数(传递函数指针,以及它需要的函数参数)
以下代码仅仅是测试代码:delphi XE7 UP1 interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.V ...
- CentOS6.5系统挂载NTFS分区的移动硬盘
CentOS6.5系统挂载NTFS分区的移动硬盘 作为IT的工作者,避免不了使用Linux系统,我如今使用的系统是CentOS6.5 X86_64位版本号,可是插入NTFS移动硬盘没有办法识别.通过以 ...
- 学习 NLP(一)—— TF-IDF
TF-IDF(Term Frequency & Inverse Document Frequency),是一种用于信息检索与数据挖掘的常用加权技术.它的主要思想是:如果某个词或短语在一篇文章中 ...
- 自定义WPF 窗口样式
原文:自定义WPF 窗口样式 Normal 0 false 7.8 pt 0 2 false false false EN-US ZH-CN X-NONE 自定义 Window 在客户端程序中,经常需 ...
- 至HDFS附加内容
在最近的项目开发中遇到的问题: 需要产生良好hdfs文件的其他内容.但使用在线版1.0.3.见发现官方文件,于1.0.4支持的文件的版本号之后append 一下是向hdfs中追加信息的操作方法 假设你 ...
- 最新用WPF为触摸屏写了一个手写程序,双格输入的
原文:最新用WPF为触摸屏写了一个手写程序,双格输入的 双格输入可以提高手写速度,当前字写完以后可以自动识别提交,写下一个字.这样比单格手写速度提高一倍.特别适合触摸屏程序使用 界面如下: 程序如下: ...