java8新特性

特性:速度更快、代码更少,强大的Stream API、便于并行、最大化减少空指针异常 Optional。核心为Lambda表达式和Stream API,总共分为以下几个部分:

  1. Lambda表达式
  2. 函数式接口
  3. 方法引用与构造器引用
  4. Stream API
  5. 接口中的默认方法与静态方法
  6. 新时间日期API
  7. 其他新特性

默认方法

Java 8中允许接口中包含具有具体实现的方法,该方法称为 “默认方法”,默认方法使用 default 关键字修饰。

一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* @author black猫
* @date 2019-11-27
* 一个接口
*/
public interface MyInterface<T> {

/***
* sayHi 抽象方法
* @param name
* @return
*/
T sayHi(String name);

/***
* sayHello 默认方法
* @param name
* @return
*/
default String sayHello(String name) {
return "Hello :" + name;
}
}

/**
* @author black猫
* @date 2019-11-28
* 实现类
*/
public class MyInterfaceImpl implements MyInterface<String> {

/***
* sayHi 方法
* @param name
* @return
*/
@Override
public String sayHi(String name) {
return "Hi :" +name;
}
}

/***
* @author black猫
* @date 2019-11-27
* 接口的实现类 测试
*/
public class MyInterfaceTest {
/***
* 测试默认方法
*/
@Test
public void test01() {
MyInterface myInterface = new MyInterfaceImpl();
// MyInterfaceImpl类并没有实现 sayHello 方法就可以调用 MyInterface接口的静态方法
System.out.println(myInterface.sayHello("Tom"));
// Hello :Tom
System.out.println(myInterface.sayHi("Jim"));
// Hi :Jim
}

}

默认方法的重写,修改MyInterfaceImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* @author black猫
* @date 2019-11-28
* 实现类
*/
public class MyInterfaceImpl implements MyInterface<String> {

/***
* sayHi 方法
* @param name
* @return
*/
@Override
public String sayHi(String name) {
return "Hi :" +name;
}

/***
* sayHello 默认方法
* @param name
* @return
*/
@Override
public String sayHello(String name) {
return "hello: "+name+" by MySuperClass...";
}

}

/**
* @author black猫
* @date 2019-11-27
* 接口的实现类 测试
*/
public class MyInterfaceTest {
/***
* 测试
*/
@Test
public void test01() {
MyInterface myInterface = new MyInterfaceImpl();
System.out.println(myInterface.sayHello("Tom"));
// hello: Tom by MySuperClass...
System.out.println(myInterface.sayHi("Jim"));
// Hi :Jim
}

}

默认方法的继承

默认的方法也可以被继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* @author black猫
* @date 2019-11-27
* 接口的实现类 测试
*/
public class MyInterfaceTest {

@Test
public void test02() {
new Interface02(){}.printHello();
// Interface01 hello!
new Interface03(){}.printHello();
// Interface03 hello!
new Interface04(){
@Override
public void printHello() {
System.out.println("Interface04 hello!");
}
}.printHello();
// Interface04 hello!
}
}
// Interface01接口里面有一默认方法
interface Interface01 {
default void printHello() {
System.out.println("Interface01 hello!");
}
}

/***
* Interface02 继承 Interface01 默认方法被继承
*/
interface Interface02 extends Interface01 {
}


/***
* Interface03 继承 Interface01 默认方法继承后重写默认方法
*/
interface Interface03 extends Interface01 {
@Override
default void printHello() {
System.out.println("Interface03 hello!");
}
}

/***
* Interface04 继承 Interface01 默认方法继承后重新定义为抽象方法
*/
interface Interface04 extends Interface01 {
@Override
void printHello();
}

默认方法的多继承

当接口的默认方法有冲突时,需要自己重写调用方法,也可以使用 InterfaceName.super.methodName(); 的方式手动调用需要的接口默认方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

// Interface05接口有一个默认方法 printHello
interface Interface05 {
default void printHello() {
System.out.println("Interface05 hello!");
}
}

// Interface06接口有一个默认方法 printHi
interface Interface06 {
default void printHi() {
System.out.println("Interface06 hi!");
}
}

// Interface07接口有两个默认方法 printHello 和 printHi
interface Interface07 {
//默认方法 printHello
default void printHello() {
System.out.println("Interface07 hello!");
}
//默认方法 printHi
default void printHi() {
System.out.println("Interface07 hi!");
}
}

// Class08 继承 Interface05和Interface06
class Class08 implements Interface05, Interface06 {

}

// 报错 Class09 继承 Interface06和Interface07
// 默认方法printHi冲突 必须选择重写一个父类的printHi
//class Class09 implements Interface06, Interface07 {
//
//}


// Class10 继承 Interface06和Interface07
// 默认方法冲突 选择一个重写
class Class10 implements Interface06, Interface07 {
@Override
public void printHi() {
//覆写存在歧义的方法,可以使用 InterfaceName.super.methodName(); 的方式手动调用需要的接口默认方法。
Interface06.super.printHi();
Interface07.super.printHi();
System.out.println("Class10 hi!");
}
}

接口和抽象类(类优先原则)

当接口继承行为发生冲突时,类的方法声明优先于接口默认方法,无论该方法是具体的还是抽象的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* @author black猫
* @date 2019-11-28
*
*/
public class AbstractTest {

public static void main(String[] args) {
Class001 class001 = new Class001();
class001.printHello();
// hello interface01...
class001.printHi();
// hi abstract01...
}

}

// 继承抽象类Abstract001 并且实现接口Interface001
class Class001 extends Abstract001 implements Interface001 {

@Override
public void printHello() {
Interface001.super.printHello();
}

}

// 一个接口有两个默认方法
interface Interface001 {
default void printHello() {
System.out.println("hello interface01...");
}

default void printHi() {
System.out.println("hi interface01...");
}
}

//一个抽象类 有一个抽象方法 一个实现的方法
abstract class Abstract001 {

abstract void printHello();

public void printHi() {
System.out.println("hi abstract01...");
}
}

接口的静态方法

接口的静态方法和类的静态方法使用一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* @author black猫
* @date 2019-11-28
* Java 8 还在允许在接口中定义静态方法。
*/
public class StaticTest {

public static void main(String[] args) {
Interface.printHelloWorld();
}

}

/**
* Interface接口有一个静态方法 printHelloWorld
*/
interface Interface {
/***
* 静态方法
*/
static void printHelloWorld() {
System.out.println("Interface11 printHelloWorld...");
}

}

我的小结

java8的接口默认方法降低了实现类之间的耦合,当需要为一个接口添加方法时,不必对所有实现类都修改。可以为接口添加新的默认方法,而不会破坏已有的接口的实现,也为升级旧接口且保持向后兼容提供了新的途径。

评论