Java 8 —— 下面主要讲 8 个特性:

一、Lambda 表达式(也可以称为“闭包”)

(paramList) -> expression;
或者
(paramList) -> {statments;}

特征:

  • 参数类型声明可选:编译器可识别参数值
  • 只有一个表达式,那么表达式的值作为 Lambda 的返回值;用大括号 {} 括起来的,多个表达式,需要使用 return 关键字指明返回值
  • Lambda 中不能声明和任何局部变量同名的,参数或者局部变量。引用的局部变量必须是 final 修饰的,否则会编译错误。可以不用显式声明 final,但是必须在 lambda 引用之前,赋值

演示用例:

public interface MathOperation {

    int operation(int a, int b);

}
public class Tester {

    public static void main(String[] args) {
MathOperation add = (int a, int b) -> a + b; //参数列表、表达式返回值相同即可;方法实现甚至可以没有:Lambda表达式相当于一个方法类,作为接口的实现
System.out.println(add.operation(1, 2));
} }

二、方法引用(方法实现,Lambda 的简写)

示例类 Car:

import java.util.function.Supplier;

public class Car {
public static Car create(final Supplier<Car> supplier) {
return supplier.get();
}
public static void collide(final Car car) {
System.out.println("Collided " + car.toString());
}
public void repair() {
System.out.println("Repaired " + this.toString());
}
public void follow(final Car another) {
System.out.println("Following the " + another.toString());
}
}

有四种引用方法:

//构造器引用 Class::new
Car car = Car.create(Car::new);
List<Car> cars = Collections.singletonList(car);
//静态方法引用 Class::static_method
cars.forEach(Car::collide);
//类引用非静态方法 Class::method
cars.forEach(Car::repair);
//对象引用非静态方法 instance::method
cars.forEach(car::follow);

运行结果:

Collided com.jackie.sms.biz.Car@81ad775
Repaired com.jackie.sms.biz.Car@81ad775
Following the com.jackie.sms.biz.Car@81ad775

三、函数式接口:

函数式接口(Functional Interface)仅有一个抽象方法,可以有多个非抽象方法(默认方法、静态方法)的接口。

如下为其定义:

@FunctionalInterface
public interface Car {
void go(Integer speed);
}

Lambda 表达式就是表示该接口抽象方法的一种实现:

Car car = System.out::println;
car.go(120);

Java 8 新增的函数式接口在下面的包中:

java.util.function

其中 Predicate<T> 接口是较为常用的一个函数式接口:它接受一个参数 T,返回一个布尔值结果。

四、接口默认方法(即接口的缺省实现方法)

其语法格式如下:

public interface Vehicle {
// default 关键字只是interface使用
default void print() {
System.out.println("我是一辆汽车");
}
}

(1)多个接口具有同名的默认方法:

//Vehicle.java
public interface Vehicle {
// default 关键字只是interface使用
default void print() {
System.out.println("我是一辆汽车");
}
} // FourWheeler.java
public interface FourWheeler {
default void print() {
System.out.println("我是一辆四轮车");
}
}

那么同一个类,实现这样的接口,会出现如下情况:

对此,可以有两种方案:

一是,类自己直接重载接口的实现方法,来覆盖这些接口的同名默认方法:

public class Car implements Vehicle, FourWheeler {
@Override
public void print() {
System.out.println("我是一辆四轮汽车");
}
}

二是,在重载方法中,使用 super 关键字,调用指定接口的默认方法(所以除了调用接口的方法,还可以有其他代码):

public class Car implements Vehicle, FourWheeler {
@Override
public void print() {
Vehicle.super.print();
FourWheeler.super.print();
System.out.println("其他");
}
}

(2)静态默认方法(除了默认实现,也可以提供静态实现):

public interface Vehicle {
static void horn() {
System.out.println("按喇叭");
}
}

可以像类一样,直接调用:

Vehicle.horn();

五、Optional 类

Optional 类是包含一个对象的一种容器,其容纳的对象可以是 null。如果值存在,则其 isPresent() 方法返回 true,调用 get() 方法返回该对象。

使用简例:

Integer num1 = null;
Integer num2 = 10;
// 此时Optional.ofNullable(num1) == Optional.empty()
Optional<Integer> a = Optional.empty();
Optional<Integer> b = Optional.of(num2); Integer c = a.orElse(0);
Integer d = b.orElse(100); System.out.println(a.isPresent());
System.out.println(b.get());
System.out.println(c);
System.out.println(d);

六、Nashorn —— Java 嵌入式的 JavaScript 引擎

Java 8 开始,Nashorn 取代 Rhino(Java 6、7),成为 Java 的 JS 引擎,性能提升了 2 到 10倍。Nashorn 完全支持ECMAScipt 5.1 规范以及一些扩展。

(1)jjs

jjs 是基于 Nashorn 的命令行工具。它接受一些 JavaScript 源码作为参数,并执行。

例如,可以创建编写 JS 文件:

// test.js
print('hello')

然后 jjs 执行此文件:

D:\>jjs test.js
hello

a)交互式编程:

D:\>jjs
jjs> print('hello')
hello
jjs> quit
function quit() { [native code] }
jjs> quit() D:\>

交互式编程 —— 传递参数(-- 没有空格):

D:\>jjs -- a b c
jjs> print(arguments.join(', '))
a, b, c
jjs>

(2)Java 中调用 JavaScript:

ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine nashorn = engineManager.getEngineByName("nashorn"); String name = "jackie";
Integer result = null; try {
nashorn.eval("print('" + name + "')"); // alert不得行。。。
result = (Integer) nashorn.eval("10 + 2");
System.out.println(result);
} catch (ScriptException e) {
e.printStackTrace();
}

(3)JavaScript 中调用 Java 类(使用 jjs 执行):

// test.js
var BigDecimal = Java.type('java.math.BigDecimal') var num1 = new BigDecimal(10)
var num2 = new BigDecimal(20)
var result = num1.multiply(num2)
.divide(new BigDecimal(100), BigDecimal.ROUND_HALF_EVEN)
print(result.toPlainString()) // 执行
D:\>jjs test.js
2

还有两个,以后再说。

记 Java 各版本新特性的更多相关文章

  1. Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结

    Atitit..jdk java 各版本新特性 1.0 1.1 1.2 1.3 1.4 1.5(5.0) 1.6(6.0) 7.0 8.0 9.0 attilax 大总结 1.1. Java的编年史2 ...

  2. Java各版本新特性总结

       Java或者说JDK的更新一般分为两部分内容:Java语言.JVM(C.C++编写),但通常情况下都不会单独发布,因为新的语言特性需要特定的JVM支持才行.下面我总结了从古至今Java各版本的新 ...

  3. java 各版本新特性

    Java 5,6,7,8,9,10,11新特性吐血总结 lkd_whh关注赞赏支持 12018.04.01 14:09:15字数 1,948阅读 10,615 作者:拔剑少年 简书地址:https:/ ...

  4. Java最近版本新特性使用介绍

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 在阅读<Thinking in Java>的过程中,并发这一章出现不少新特性,工作中也有 ...

  5. Atitit opencv版本新特性attilax总结

    Atitit opencv版本新特性attilax总结 1.1. :OpenCV 3.0 发布,史上功能最全,速度最快的版1 1.2. 应用领域2 1.3. OPENCV2.4.3改进 2.4.2就有 ...

  6. Atitit 发帖机系列(8)  词法分析器v5 版本新特性说明)

    Atitit 发帖机系列(8)  词法分析器v5 版本新特性说明) v5  增加对sql单引号的内部支持.可以作为string 结构调整,使用递归法重构循环发..放弃循环发. V4 java dsl词 ...

  7. JDK各版本新特性!

    1.JDK1.5 新特性 1.自动装箱与拆箱:自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中.自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取 ...

  8. [转] Java 8的新特性

    简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的例子 ...

  9. Java 8的新特性—终极版

    作者:杜琪[译] 原文链接:http://www.jianshu.com/p/5b800057f2d8 1. 简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本 ...

随机推荐

  1. java 查看线程死锁

    那我们怎么确定一定是死锁呢?有两种方法. 1>使用JDK给我们的的工具JConsole,可以通过打开cmd然后输入jconsole打开. 1)连接到需要查看的进程.

  2. 转 Kafka、RabbitMQ、RocketMQ等消息中间件的对比 —— 消息发送性能和优势

    Kafka.RabbitMQ.RocketMQ等消息中间件的对比 —— 消息发送性能和优势 引言 分布式系统中,我们广泛运用消息中间件进行系统间的数据交换,便于异步解耦.现在开源的消息中间件有很多,前 ...

  3. 解决HTML5提出的新的元素不被IE6-8识别的解决办法

    解决HTML5提出的新的元素不被IE6-8识别的解决办法 <!--[if lt IE 9]> <script type="text/javascript" src ...

  4. ES6 字符串

    拓展的方法 子串的识别 ES6 之前判断字符串是否包含子串,用 indexOf 方法,ES6 新增了子串的识别方法. includes():返回布尔值,判断是否找到参数字符串. startsWith( ...

  5. Ubuntu上Qt之简单图片浏览器

     >>主要功能: (1)图片切换浏览,上一张/下一张. (2)图片放大.缩小.包括两种机制:鼠标滚轮和按钮放大/缩小. (3)图片自动循环播放,间隔2s.点击播放后,其他操作均无效,直至点 ...

  6. [js]js栈内存的全局/私有作用域,代码预解释

    js代码如何执行的 浏览器提供执行环境: 全局作用域(提供js执行环境, 栈内存) --> 执行js需要预解释 - 带var : 提前声明 - 带function关键字的: 提前声明+定义 js ...

  7. openshift 容器云从入门到崩溃之五《部署应用》

    1.配置部署模板 配置好用户权限之后就可以部署应用了oc常用的两种部署方式: Deploy Image方式 优点:这种方式是最简单的部署方式,你只需要有一个容器镜像就行了或者公开的docker hub ...

  8. Go 初体验 - channel.1 - 基本用法

    channel 分为两种: 1. 无缓冲 channel 2. 缓冲 channel 无缓冲 channel 的使用必须遵循一个原则:推送和读取必须同时存在,否则就发生死锁 先上代码: 这里定义了一个 ...

  9. Go 初体验 - 死锁的几种情况

    go 语言里,channel 是一个重要的对象和概念,它是通信的基础实现 如何实例化: ch := make(chan int) 由 channel 通信引起的死锁共有3种: 第一种是因为给 ch 推 ...

  10. centos共享目录

    使用VirtualBOX自带的共享文件夹功能 运行环境:  - 宿主机:windows 10  - 虚拟机:CentOS 7(我当初是按照Ubuntu环境下的教程弄的,所以其他Linux版本也可以参考 ...