模块化系统

在Java9版本中,推出了模块化概念。可以让我们编写代码时分模块来开发,避免代码逻辑变得复杂。提高系统的安全性和可维护性。

首先新建两个 Module,分别右键 src 新建 module-info.java 文件

createmodule-info.png

新建完成结构如下

Module.png

我们将 main2 模块下的 Person 导出,在 main 模块中引入。编写 main2 模块下的 module-infpo.java 文件如下

1
2
3
module main2 {
exports com.songzx.java9test;
}

然后在main 模块的 module-infpo.java 文件中导入 main2

1
2
3
module main {
requires main2;
}

导入后我们就可以在 main 模块中使用另外一个模块的自定义类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.songzx.java;

import com.songzx.java9test.Person;

/**
* @author songzx
* @create 2022-02-11 14:59
*/
public class java1 {
public static void main(String[] args) {
Person p = new Person("lisi",15);
System.out.println(p); //=> Person{name='lisi', age=15}
}
}

接口中声明私有方法

java9 中可以在接口中声明私有方法,私有方法只能在接口内部使用,外界无法使用。

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
package com.songzx.java;

/**
* @author songzx
* @create 2022-02-11 16:26
*/
public class java2{
public static void main(String[] args) {
MyClass myClass = new MyClass();
myClass.methodDefault();
myClass.methodPublic();

// 接口中的静态方法只能由接口本身调用
MyInterface.methodStatic();

// 接口中的私有方法不能被外界调用
// MyInterface.methodPrivate();
}
}
interface MyInterface{
void methodPublic();

static void methodStatic(){
System.out.println("接口中的静态方法");
}

default void methodDefault(){
System.out.println("我是接口中的默认方法");
methodPrivate();
};

// 只在 java9 以及以上版本适用
private void methodPrivate(){
System.out.println("我的接口中的私有方法");
}
}

class MyClass implements MyInterface{

@Override
public void methodPublic() {
System.out.println("接口实现类的公共方法");
}

@Override
public void methodDefault() {
System.out.println("接口实现类重写默认方法");
}
}

泛型结构特性升级

java9 中使用泛型时可以省略第二个尖括号中的数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.songzx.java;

import java.util.Comparator;

/**
* @author songzx
* @create 2022-02-11 16:55
*/
public class java3 {
public static void main(String[] args) {
// 在java9中可以省略后面尖括号中的数据类型,在java8及以下会报错
Comparator<Object> com = new Comparator<>() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
};
}
}

String 底层存储结构变化

在 Java9 之后,String 底层改为使用 byte[] 来存储,节约了一些空间。跟着改变的还要与之相关的 StringBufferStringBuilder

创建只读集合

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
package com.songzx.java;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* @author songzx
* @create 2022-02-11 17:51
*/
public class java5 {
@Test
public void test1(){
// 调用 of 方法创建的集合都是只读的
List<Integer> integerList = List.of(1, 2, 3, 4);
// integerList.add(45); //=> java.lang.UnsupportedOperationException
System.out.println(integerList);

Set<Integer> set = Set.of(1, 122, 22, 113, 5);
// set.add(1111); 添加报错
System.out.println(set);

Map<String, String> map = Map.of("name", "lisi", "age", "18");
System.out.println(map);

}
}

transferTo 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.songzx.java;

import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
* @author songzhengxiang
* @create 2022-02-12 14:59
*/
public class java6 {
public static void main(String[] args) {
// 将 main/src/hello.txt 文件中的内容复制到 hello_copy.txt 文件在
try(FileInputStream fis = new FileInputStream("main/src/hello.txt")){
FileOutputStream fos = new FileOutputStream("hello_copy.txt");
// 使用 transferTo 将读取到的文件直接写入到一个新文件中
fis.transferTo(fos);
}catch (Exception e){
e.printStackTrace();
}
}
}

Stream 的新增方法

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
package com.songzx.java;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
* @author songzhengxiang
* @create 2022-02-12 15:24
*/
public class java7 {
public static void main(String[] args) {
List<Integer> integerList = Arrays.asList(12, 26, 5, 4, 32, 21, 12, 45, 32);
Stream<Integer> stream = integerList.stream();
// takeWhile 返回从头开始的尽量多的元素,遇到第一个不满足时就截止,不往后继续输出
//stream.takeWhile(i->i<30).forEach(System.out::println);

// dropWhile 和 takeWhile 相反,如果满足条件则不要,从开始不满足条件的地方一直往后输出
stream.dropWhile(i->i<30).forEach(System.out::println);
}

@Test
public void test(){
// 创建一个无限流,只输出10次
Stream.iterate(0,i-> i + 1).limit(10).forEach(System.out::println);

// java9 中提供了 iterate 的重写方法,可以添加限制条件,x < 10 时停止输出
Stream.iterate(0,x->x<10,x->x+1).forEach(System.out::println);
}
}

局部变量类型推断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.songzx.java;

import org.junit.Test;

import java.util.ArrayList;

/**
* @author songzhengxiang
* @create 2022-02-12 16:20
*/
public class java8 {
@Test
public void test(){
// 局部变量的类型推断
var name = "lisi";
var age = 15;

var strings = new ArrayList<>();

var random = Math.random();
}
}

copyof 方法的使用

如果 copyOf(coll) 方法中的 coll 已经是只读的,则返回的还是 coll ,如果 coll 不是只读的,则会新创建一个只读的集合,所以第二个判断中返回 false

1
2
3
4
5
6
7
8
9
10
@Test
public void test1(){
var list = List.of(1, 2, 3);
var list1 = List.copyOf(list);
System.out.println(list == list1); //=> true

var intlist = Arrays.asList(1,2,3);
var intlist2 = List.copyOf(intlist);
System.out.println(intlist == intlist2); //=> false
}

字符串新增方法

  • isBlank 判断字符串是否为空
  • strip 去除字符串首尾空格
  • stripTrailing 去除尾部空格
  • stripLeading 去除头部空格
  • repeat 循环字符串
  • lines().count() 统计字符串行数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// isBlank 判断字符串是否为空
System.out.println(" \t \t \n ".isBlank());
// strip 去除字符串首尾空格
System.out.println("---" + "\t\tabc\t\t".strip() + "------");
// stripTrailing 去除尾部空格
System.out.println(" hello world ".stripTrailing());
// stripLeading 去除头部空格
System.out.println(" hello world ".stripLeading());
// repeat 循环字符串
System.out.println("java".repeat(5)); //=> javajavajavajavajava

// lines().count() 统计字符串行数
String desc = "111\n222\n333";
System.out.println(desc.lines().count()); //=> 3