目录 start

  1. Java5
  2. Java6
  3. Java7
    1. 异常处理
    2. TWR
    3. NIO 2.0
      1. Path
      2. 文件系统 I/O
      3. 异步 I/O

目录 end|2019-10-19 17:04|


参考博客: JDK各个版本比较 JDK5~JDK10

Java5

  • complete

Java6

  • complete

Java7

小特性

  • Switch 支持 String
    • Java6之前case语句中的常亮只支持 byte, char, short, int或枚举变量,Java7中增加了String
  • 二进制数值的转换
    • 原本是 int x = Integer.parseInt("1010100", 2);Java7之后int x = 0b110110;
  • 数字下划线 10_0100__1000__0011
  • 钻石语法: 泛型右部直接<>不用写类型变量

异常处理

  • 异常处理
    • 允许异常的操作 catch(IOException | NullPointException e)
    • final关键字: catch (final Exception e){throw e;} 抛出后的是原异常类型的异常而不是Exception

TWR

  • TWR(try with resources)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 从URL下载文件, 其中的资源都会自动关闭
    // 但是要注意发生异常后,资源也不会自动关闭, 所以确保TWR生效,正确的用法是为各个资源声明独立变量.
    try(OutputStream out = new FileOutputStream(file);
    InputStream is = url.openStream()){
    byte[] buf = new byte[1024];
    int len;
    while ((len = is.read(buf)) > 0){
    out.write(buf, 0, len);
    }
    }
  • 另一个好处就是改善了错误跟踪的能力, 能够更准确地跟踪堆栈中的异常, 在Java7之前,处理资源时抛出的异常经常会被覆盖,TWR也可能会出现这种情况.

    1
    2
    3
    try((InputStream in = getNullStream())){
    in.available();
    }
  • 在这种改进后的跟踪堆栈中能看到提示, 其中的NullPointException是能够抛出来看到的.没有被隐藏

目前TWR特性依靠一个接口来实现 AutoCloseable. TWR的try从句中出现的资源类都必须实现这个接口. Java7中大部分资源类都修改过
但不是所有的资源类都采用了这项技术, JDBC是已经具备了这个特性. 官方提倡尽量采用TWR替代原有的方式


简化变参方法调用

1
2
3
4
5
6
7
8
9
// 不允许创建已知类型的泛型数组, 编译报错
HashMap<String, String>[] array = new HashMap<>[2];

// 只能这样写 这样的编写也只是权宜之计, 编译器会警告:
// 可以将array定义为HashMap<String, String>数组,但是又不能创建这个类型的实例 所以这里只是将原始类型实例化了放进去.
HashMap<String, String>[] array = new HashMap[2];

// 现在能够这样编写:
public static <T> Collection<T> doSomething(T... entries){}

NIO 2.0

Path

1
2
3
4
5
6
7
8
9
10
11
12
// 创建路径
Path list = Paths.get("xmlStudy");
// 获取文件名
System.out.println(list.getFileName());
// 获取名称元素数量
System.out.println(list.getNameCount());

File file = new File("test.xml");
// 将旧API的File转换成新的Path
Path path = file.toPath();
// 将Path转换成File
File fiel2 = path.toFile();

文件系统 I/O

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 创建文件
Path path = Paths.get("test2.xml");
Path file = Files.createFile(path);
// 删除文件
Files.delete(path);

// 复制
Path source = Paths.get("test2.xml");
Path path = Paths.get("src/test2.xml");
Files.copy(source, path);
// 移动
Path path = Paths.get("test2.xml");
Path source = Paths.get("src/test2.xml");
Files.move(source, path);
  • 读写数据 (可指定文件的打开方式, WRITE, READ, APPEND (StandardOpenOption.WRITE))
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Path path = Paths.get("test.txt");
    // 打开一个带缓冲区的读取器
    try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
    String line;
    while ((line = reader.readLine()) != null) {
    System.out.println(line);
    }
    }

    // 打开带有一个缓冲区的写入器
    try (BufferedWriter writer = Files.newBufferedWriter(path)) {
    writer.write("测试");
    }

    // java7简化后的读取全部行和字节
    List<String> lines = Files.readAllLines(path);
    byte[] bytes = Files.readAllBytes(path);
    System.out.println(lines);

异步 I/O

  • 将来式
1
2
3
4
5
6
7
8
9
10
11
12
Path path = Paths.get("test.txt");
// 异步打开文件
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);
// 读取100000字节
ByteBuffer buffer = ByteBuffer.allocate(100_000);
Future<Integer> result = channel.read(buffer, 0);
while (!result.isDone()) {
System.out.println("其他事");
}
// 获取结果
Integer bytesRead = result.get();
System.out.println(bytesRead);
  • 回调式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Path path = Paths.get("test.txt");
// 异步打开文件
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);
// 读取100000字节
ByteBuffer buffer = ByteBuffer.allocate(100_000);

channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
// 读取调取完成时的回调方法
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println(result);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println(exc.getMessage());
}
});