由于工作需要,最近研究了一下Java8的新特性,主要包括以下几个方面:
1、Lambda 表达式
Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中。
2、方法引用
方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
3、函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
4、Stream API
新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。
5、Date Time API
加强对日期与时间的处理。
6、Optional 类
Optional 类已经成为 Java 8 类库的一部分,用来解决空指针异常。
7、Nashorn, JavaScript 引擎
Java 8提供了一个新的Nashorn javascript引擎,它允许我们在JVM上运行特定的javascript应用。
8、Base64
在Java 8中,Base64编码已经成为Java类库的标准。
Java 8 内置了 Base64编码的编码器和解码器。
上一篇的转载相当于是总的来说了一下lambda表达式与其他各种新特性的配合实现。接下来,我将把自己学习到的每个特性的具体实现呈现给大家。
本篇就先说一下lambda表达式:
1、语法格式
(parameters) -> expression
或
(parameters) ->{ statements; }
2、重要特征
1)可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
2)可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
3)可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
4)可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
demo如下:
package com.wj.java8.testPackage.lambdaTest;
public class lambdaTest {
public static void main(String args[]){
lambdaTest tester = new lambdaTest();
// 类型声明
MathOperation addition = (int a, int b) -> a + b;
// 不用类型声明
MathOperation subtraction = (a, b) -> a - b;
// 大括号中的返回语句
MathOperation multiplication = (int a, int b) -> { return a * b; };
// 没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;
System.out.println("9 + 3 = " + tester.operate(9, 3, addition));
System.out.println("9 - 3 = " + tester.operate(9, 3, subtraction));
System.out.println("9 x 3 = " + tester.operate(9, 3, multiplication));
System.out.println("9 / 3 = " + tester.operate(9, 3, division));
// 不用括号
GreetingService greetService1 = message ->
System.out.println("Hello " + message);
// 用括号
GreetingService greetService2 = (message) ->
System.out.println("Hello " + message);
greetService1.sayMessage("wj");
greetService2.sayMessage("wangjie");
}
interface MathOperation {
int operation(int a, int b);
}
interface GreetingService {
void sayMessage(String message);
}
private int operate(int a, int b, MathOperation mathOperation){
return mathOperation.operation(a, b);
}
}
输出结果为:
9 + 3 = 12
9 - 3 = 6
9 x 3 = 27
9 / 3 = 3
Hello wj
Hello wangjie
3、变量作用域
1)lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
public class Java8Tester {
final static String salutation = "Hello! ";
public static void main(String args[]){
GreetingService greetService1 = message ->
System.out.println(salutation + message);
greetService1.sayMessage("wangjie");
}
interface GreetingService {
void sayMessage(String message);
}
}
结果:
Hello! wangjie
2)注意:Error:(14, 56) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
出现这个错误是因为lambda 表达式的局部变量虽然可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
如下代码:
int num =1;
//int finalNum = num;
MathOperation mathOperation = (int a, int b)-> num +b;
num =5;
就会出现这个问题。
3)在labmda表达式中不允许生命与参数名称相同的参数,例如:
int a=1;
MathOperation mathOperation = (int a, int b)-> num +b;
会报错
4、接口的方法可以允许有方法体
使用lamda表达式,接口中只允许有一个没有方法体的方法,有方法体的方法必须指定访问类型(default或者static)
如下代码:
public class MyTest {
public static void main(String[] args) {
MyTest test = new MyTest();
//1)可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
MathOperation addtion = (int a, int b)-> a +b;
MathOperation reduce = (a,b)->a-b;
MathOperation multiOperation = (int a,int b)->{return a*b;};
System.out.println("10+5:" + addtion.operate(10,5));
System.out.println("10-5:" + test.operate(10,5,reduce));
//执行接口中的default的方法
System.out.println("10*5:" + multiOperation.test1(10,5));
//执行接口中的静态方法
System.out.println("10/5:" + MathOperation.test2(10,5));
}
private int operate(int a,int b,MathOperation mathOperation){
return mathOperation.operate(a,b);
}
interface MathOperation{
//一个没有方法体的方法
int operate(int a,int b);
//default方法
default int test1(int b, int c) {
return b*c;
}
//static方法
static int test2(int b, int c) {
return b/c;
}
}}