教练, 我想学java的新特征

java的新特征

    • 各个版本的重大更新
      • java 8
        • CompletableFuture
        • Date/Time API
      • java 9
        • G1 垃圾回收器作为默认的垃圾回收器
        • HTTP/2 客户端
        • 模块化系统
      • Java 10
        • 局部变量类型推断
      • Java 11
        • ZGC低延迟垃圾回收器
        • HTTP/2 服务器
        • 嵌套访问控制
      • Java 12
        • 新的 switch 语法
        • Shenandoah 垃圾回收器
      • Java 13
        • Text Blocks
        • Switch 表达式增强
        • 线程局部握手
      • Java 14
        • Records 类型
        • JFR 飞行器
      • Java 15
        • 递归式删除文件
      • Java 16
        • 静态成员类的上下文引用
        • 本地变量类型推断升级
        • Vector
      • Java 17
        • Records 类型增强
        • Sealed 类型

教练, java版本一直更新, 我想了解一下从java8到java17之间的重大变化特征

各个版本的重大更新

Java 8:

  1. Lambda 表达式和函数式接口:可以使得代码更加简洁和易读

  2. 流式 API:可以用来处理集合和数组,可以使得代码更加简洁和易读

  3. Optional 类型:可以避免空指针异常,可以使得代码更加健壮和可读

  4. 接口默认方法:可以使得接口的演化更加灵活和兼容性更好

  5. Date/Time API:可以更加方便地处理日期和时间,可以避免旧的 Date 类型的一些问题

  6. CompletableFuture: 提供了一种简单的方式来处理异步任务

Java 9:

  1. 模块化系统:可以用来管理和组织 Java 应用程序的代码,可以使得应用程序更加健壮和可维护

  2. HTTP/2 客户端:内置的 HTTP/2 客户端,可以提高通信性能和可靠性

  3. 进程 API:可以用来管理和控制本地进程,可以使得应用程序更加灵活和可控

  4. 安全性增强:支持 TLS 1.2 和 TLS 1.3 协议,增强了 XML 处理的安全性,增强了强密码算法的支持,等等,可以使得 Java 应用程序更加安全

  5. 新的 GC: 引入了 G1 垃圾回收器作为默认的垃圾回收器,它可以更好地处理大型堆

Java 10:

  1. 局部变量类型推断:可以使得代码更加简洁和易读

  2. 推断类型变量:可以在一些场景下省略类型变量,可以使得代码更加简洁和易读

  3. Unicode 10.0 支持:可以处理更多的字符集和语言

Java 11:

  1. ZGC低延迟垃圾回收器:可以使得应用程序的响应更加快速和可靠, 可以在数毫秒的时间内处理数百 GB 的堆

  2. HTTP/2 服务器:内置的 HTTP/2 服务器,可以提供高性能的 Web 服务

  3. 嵌套访问控制:可以使得在类内部更加灵活地控制访问权限

Java 12:

  1. Switch 表达式:可以用来替代 Switch 语句,可以使得代码更加简洁和易读
  2. Shenandoah 垃圾回收器:引入了一种新的垃圾回收器 Shenandoah,可以在几乎不会停顿的情况下进行大规模的内存回收

Java 13:

  1. Text Blocks:可以使得多行字符串的编写更加方便和易读

  2. Switch 表达式增强:可以在 Switch 表达式中使用 Yield 语句,可以使得代码更加灵活和易读

  3. 线程局部握手: 引入了线程局部握手 API,使得开发人员可以更加灵活地管理线程局部状态

Java 14:

  1. Records 类型:可以用来定义不可变数据对象,可以使得代码更加简洁和易读

  2. JFR 飞行器:可以用来监控和调优 Java 应用程序,可以提高应用程序的性能和可靠性

Java 15:

  1. 递归式删除文件:Java 15 引入了一个新的 API,可以进行递归式的删除文件,包括目录和非空目录

Java 16:

  1. 静态成员类的上下文引用:可以在静态成员类中使用外部类的 this 引用,可以使得代码更加灵活和易读。

  2. 本地变量类型推断升级:可以在更多的场景下使用,可以使得代码更加简洁和易读。

  3. Vector API: 引入了 Vector API,一种用于高性能数值计算的 API

Java 17:

  1. Records 类型增强:可以更加灵活地定义 Records 类型,可以使得代码更加简洁和易读
  2. Sealed 类型: 密封类,指定接口由哪些类实现

java 8

CompletableFuture

Java 8 引入了 CompletableFuture 类,提供了一种简单的方式来处理异步任务。CompletableFuture 可以用来处理异步任务的结果,还可以将多个异步任务组合在一起。

示例代码:

// 使用 CompletableFuture 处理异步任务
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    // 异步任务
    return "Hello World";
});
future.thenAccept(result -> {
    // 处理异步任务的结果
    System.out.println(result);
});

使用 CompletableFuture 可以使得异步任务更加容易处理,但是要注意避免死锁和线程安全问题。

Date/Time API

Java 8 引入了全新的日期和时间 API,可以更加方便地进行日期和时间的处理。Date/Time API 支持时区和夏令时,也提供了一些方便的方法来处理日期和时间。

示例代码:

// 使用 LocalDate 进行日期的操作
LocalDate today = LocalDate.now();
LocalDate tomorrow = today.plusDays(1);
System.out.println("Today: " + today);
System.out.println("Tomorrow: " + tomorrow);

Date/Time API 中的类都是不可变的,因此它们是线程安全的。

java 9

G1 垃圾回收器作为默认的垃圾回收器

引入了 G1 垃圾回收器作为默认的垃圾回收器,它可以更好地处理大型堆。G1 垃圾回收器可以将堆分成多个区域,以便更加高效地执行垃圾回收

使用 G1 垃圾回收器可以提高大型应用程序的性能,但是要注意避免过多使用内存。

HTTP/2 客户端

全新的 HTTP/2 客户端 API,可以帮助开发人员更轻松地使用 HTTP/2 协议,从而提高网络通信的效率和性能。

Java 9 的 HTTP/2 客户端 API 包含了以下特性:

  1. 非阻塞的 API:HTTP/2 客户端 API 提供了一个非阻塞的 API,可以更好地利用底层的异步 I/O 机制,从而提高网络通信的效率和性能。

  2. 流式处理 API:HTTP/2 客户端 API 提供了一个流式处理的 API,可以更轻松地处理大量的 HTTP/2 流,从而提高网络通信的吞吐量和响应速度。

  3. 支持 WebSocket:HTTP/2 客户端 API 支持 WebSocket 协议,可以更轻松地实现双向通信和实时通信的功能。

下面是一个简单的示例,展示了如何使用 HTTP/2 客户端 API:


import java.net.URI;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Http2ClientExample {
    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
        HttpClient httpClient = HttpClient.newHttpClient();
        HttpRequest httpRequest = HttpRequest.newBuilder()
                .uri(URI.create("https://www.example.com"))
                .build();
        CompletableFuture<HttpResponse<String>> responseFuture = httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString());
        HttpResponse<String> response = responseFuture.get(10, TimeUnit.SECONDS);
        System.out.println(response.body());
    }
}

在这个示例中,使用 HTTP/2 客户端 API 发送一个 HTTP GET 请求,获取 https://www.example.com 网站的响应结果,并将响应结果打印到控制台上。使用 HTTP/2 客户端 API,只需要创建一个 HttpClient 实例,并使用 sendAsync() 方法发送异步请求,即可轻松地发送 HTTP/2 请求,并处理 HTTP/2 响应。

模块化系统

它可以帮助开发人员更好地管理代码和依赖项。模块化系统将代码划分为模块,每个模块都可以指定依赖项和可见性。

创建一个新的 Java 9 项目,创建一个名为 mymodule 的模块,并在该模块中创建一个名为 com.example.mymodule 的包,以及一个名为 MyClass 的类:

├── mymodule
│   ├── src
│   │   ├── com.example.mymodule
│   │   │   └── MyClass.java
│   │   └── module-info.java
│   └── test
│       └── com.example.mymodule
│           └── MyClassTest.java
└── pom.xml

module-info.java 文件中,声明 mymodule 模块依赖于 java.base 模块,并导出 com.example.mymodule 包:

module mymodule {
    requires java.base;
    exports com.example.mymodule;
}

MyClass.java 文件中,实现一个简单的类,用于打印一句话:

package com.example.mymodule;

public class MyClass {
    public void sayHello() {
        System.out.println("Hello from com.example.mymodule!");
    }
}

MyClassTest.java 文件中,编写一个简单的测试类,用于测试 MyClass 类的 sayHello() 方法:

package com.example.mymodule;

import org.junit.jupiter.api.Test;

class MyClassTest {
    @Test
    void sayHello() {
        MyClass myClass = new MyClass();
        myClass.sayHello();
    }
}

然后,创建一个新的模块 myapp,用于引用 mymodule 模块中的代码:

├── myapp
│   ├── src
│   │   └── com.example.myapp
│   │       └── MyApp.java
│   └── test
│       └── com.example.myapp
│           └── MyAppTest.java
└── pom.xml

module-info.java 文件中,声明 myapp 模块依赖于 mymodule 模块:

module myapp {
    requires mymodule;
}

MyApp.java 文件中,编写一个简单的类,用于引用 mymodule 模块中的 MyClass 类:

package com.example.myapp;

import com.example.mymodule.MyClass;

public class MyApp {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.sayHello();
    }
}

MyAppTest.java 文件中,编写一个简单的测试类,用于测试 MyApp 类的 main() 方法:

package com.example.myapp;

import org.junit.jupiter.api.Test;

class MyAppTest {
    @Test
    void main() {
        MyApp.main(new String[]{});
    }
}

Java 10

局部变量类型推断

局部变量类型推断。这个特性可以让程序员在不明确指定变量类型的情况下,根据变量的初始值来推断变量的类型。这样可以使得代码更加简洁、易读和易维护。

在 Java 10 中,可以使用关键字 var 来声明一个局部变量,然后根据变量的初始值来自动推断变量的类型。使用 var 声明的变量的类型是由编译器自动推断的,可以是任何有效的 Java 类型,包括基本类型和引用类型。

下面是一个简单的示例,展示了如何使用局部变量类型推断:

import java.util.*;

public class LocalVariableTypeInference {
    public static void main(String[] args) {
        var list = new ArrayList<String>();
        list.add("apple");
        list.add("banana");
        list.add("orange");

        var iterator = list.iterator();
        while (iterator.hasNext()) {
            var element = iterator.next();
            System.out.println(element);
        }
    }
}

在这个示例中,使用 var 声明了一个 ArrayList 和一个 Iterator,然后使用 while 循环遍历集合中的元素,并使用 var 声明了一个变量 element,用于保存迭代器返回的元素。编译器可以根据集合中的元素类型来自动推断 element 的类型为 String。

需要注意的是,局部变量类型推断可以使得代码更加简洁,但也可能会导致可读性下降和代码难以理解。因此,需要在使用时谨慎考虑,避免滥用局部变量类型推断。同时,需要注意,局部变量类型推断只适用于局部变量,不适用于方法的参数、方法的返回值、类的成员变量和静态变量等。

Java 11

ZGC低延迟垃圾回收器

ZGC,一种低延迟的垃圾回收器,可以在数毫秒的时间内处理数百 GB 的堆。ZGC 可以并发执行垃圾回收,减少应用程序的停顿时间。

HTTP/2 服务器

引入了一个内置的 HTTP/2 服务器,可以用来替代传统的基于 Servlet 容器的 HTTP 服务器。这个 HTTP/2 服务器可以提供更高效、更安全和更灵活的 Web 服务。

HTTP/2 是 HTTP/1 的一种新版本,它可以通过多路复用和二进制协议等特性,提高网络传输效率和安全性,支持更多的流量和更快的速度。Java 11 的 HTTP/2 服务器可以支持以下特性:

  1. 多路复用:HTTP/2 服务器可以使用一个 TCP 连接同时处理多个请求和响应,提高了网络传输效率和速度。

  2. 流量控制:HTTP/2 服务器可以根据客户端的需求和网络状况,自动控制数据的传输速度和流量。

  3. 服务器推送:HTTP/2 服务器可以主动向客户端推送资源,提高了客户端的访问速度和响应性。

  4. 安全性增强:HTTP/2 服务器可以使用 TLS 加密协议,保护传输过程中的数据安全性。

下面是一个简单的示例,展示了如何使用 Java 11 的 HTTP/2 服务器:

import com.sun.net.httpserver.*;

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class Http2Server {
    public static void main(String[] args) throws IOException {
        int port = 8080;
        HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
        server.createContext("/", new MyHandler());
        server.setExecutor(Executors.newFixedThreadPool(10));
        server.start();
        System.out.println("Server is listening on port " + port);
    }

    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            String response = "Hello, world!";
            exchange.sendResponseHeaders(200, response.getBytes().length);
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

在这个示例中,定义了一个 Http2Server 类,它使用 HttpServer 类创建一个 HTTP/2 服务器,并指定监听的端口号。创建了一个 MyHandler 类来处理请求,并返回一个 “Hello, world!” 的字符串。然后使用 Executors 类创建一个线程池来处理请求,并启动 HTTP/2 服务器。

Java 11 的 HTTP/2 服务器可以提供更高效、更安全和更灵活的 Web 服务,尤其是在处理大量的并发请求时,可以提高性能和可伸缩性。

嵌套访问控制

嵌套访问控制,可以使得在类内部更加灵活地控制访问权限。嵌套访问控制可以将一个类的访问控制扩展到另一个类中。

示例代码:

// 使用嵌套访问控制
public class Outer {
    private int value;
    public class Inner {
        private void setValue(int value) {
            Outer.this.value = value;
        }
    }
}

使用嵌套访问控制可以使得代码更加清晰和可维护,但是要注意遵循最佳实践和避免滥用访问控制。

Java 12

新的 switch 语法

Java 12 引入了新的 switch 语法,使得在 switch 语句中可以使用更加灵活的语法。新的 switch 语法支持使用表达式作为 case 标签,还支持使用箭头语法进行多个标签的组合。

示例代码:

// 使用新的 switch 语法
String fruit = "apple";
int price = switch (fruit) {
    case "apple", "pear" -> 2;
    case "orange", "banana" -> 3;
    default -> 0;
};
System.out.println(price);

使用新的 switch 语法可以使得代码更加简洁和易读,但是要注意避免滥用新语法。

Shenandoah 垃圾回收器

Shenandoah 垃圾回收器是 Java 12 中引入的一种新的垃圾回收器,它是一种低暂停时间垃圾回收器,可以在几乎不会停顿的情况下进行大规模的内存回收。

Shenandoah 垃圾回收器的主要特点包括:

  1. 低停顿时间:Shenandoah 垃圾回收器采用了一种新的垃圾回收算法,可以在几乎不会停顿的情况下进行内存回收,从而提高了应用程序的响应性和性能。

  2. 大规模内存回收:Shenandoah 垃圾回收器可以在大规模的内存回收时仍然保持低停顿时间,并且不需要额外的内存空间来进行垃圾回收。

  3. 跨全局存储区的并发标记:Shenandoah 垃圾回收器使用了一种新的算法来进行并发标记,并且可以在跨全局存储区时仍然保持低停顿时间。

需要注意的是,Shenandoah 垃圾回收器是一种实验性的功能,需要使用 -XX:+UnlockExperimentalVMOptions 参数来启用。并且,它并不适用于所有的应用程序和场景,需要根据实际情况进行评估和测试。在某些场景下,可能会导致性能下降或内存使用增加。

Java 13

Text Blocks

Text Blocks,一种用于编写多行字符串的新语法。Text Blocks 可以使得多行字符串的编写更加方便和易读。

// 使用 Text Blocks
String html = """

    
        

Hello, World!

"""
; System.out.println(html);

Switch 表达式增强

Switch 表达式的增强功能。Switch 表达式可以用来根据不同的值执行不同的代码块,可以替代一系列的 if-else 语句。Switch 表达式的增强功能可以使得代码更加简洁、易读和高效。

具体来说,Switch 表达式的增强功能包括:

  1. 简化的 Switch 表达式:可以在一个表达式中使用 Switch,而不需要使用单独的语句。使用 -> 运算符可以将 Switch 的每个 case 语句映射到一个表达式,可以使得代码更加简洁。

  2. 多个 case 语句共享代码块:可以使用逗号将多个 case 语句组合到一起,共享同一个代码块。

  3. 新的 yield 关键字:可以在 Switch 表达式中使用新的 yield 关键字来返回一个值。yield 语句可以放在一个 case 语句的结尾,表示这个 case 语句返回一个值。

下面是一个简单的示例,展示了如何使用 Switch 表达式的增强功能:

public class SwitchEnhancement {
    public static void main(String[] args) {
        int day = 3;

        String dayType = switch (day) {
            case 1, 2, 3, 4, 5 -> "weekday";
            case 6, 7 -> "weekend";
            default -> throw new IllegalArgumentException("Invalid day: " + day);
        };

        System.out.println(dayType);
    }
}

在这个示例中,定义了一个 SwitchEnhancement 类,它包含一个 main 方法,该方法使用 Switch 表达式来根据不同的值返回不同的字符串。使用逗号将多个 case 语句组合到一起,共享同一个代码块。使用默认语句抛出一个异常,表示如果 day 的值不在 1 到 7 之间,则抛出一个异常。

Switch 表达式的增强功能可以使得代码更加简洁、易读和高效,尤其是在处理大量的 if-else 语句时,可以提高代码的可读性和可维护性。

线程局部握手

线程局部握手 API,使得开发人员可以更加灵活地管理线程局部状态。线程局部握手可以在线程启动时设置一个默认值,也可以在运行时动态更改值。

示例代码:

// 使用线程局部握手 API
ThreadLocal<String> threadLocal = new ThreadLocal<>();
threadLocal.set("Hello World");
Runnable runnable = () -> {
    String value = threadLocal.get();
    System.out.println(value);
};
new Thread(runnable).start();

使用线程局部握手可以使得线程间的数据共享更加安全和可控,但是要注意避免过多使用线程局部状态。

Java 14

Records 类型

Records 类型,一种新的数据类型,可以更加方便地定义不可变的数据类。Records 类型提供了一种简洁的方式来定义只包含数据的类,可以自动为所有属性生成 getter 方法和 equals/hashCode 方法。

// 定义一个 Records 类型
public record Person(String name, int age) {}

// 使用 Records 类型
Person person = new Person("Alice", 20);
System.out.println(person.name());
System.out.println(person.age());

使用 Records 类型可以使得代码更加简洁和易读,但是要注意避免过度使用 Records 类型。

JFR 飞行器

JFR(Java Flight Recorder)飞行器,这是一个用于监控和调优 Java 应用程序的工具。JFR 可以记录应用程序的运行时行为和性能指标,可以用来分析和优化应用程序的性能。

示例代码:

// 启用 JFR 飞行器
java -XX:StartFlightRecording

使用 JFR 飞行器可以使得监控和调优应用程序更加方便和高效,但是要注意遵循最佳实践和避免滥用 JFR 飞行器。

需要注意的是,JFR 飞行器是 Oracle JDK 的一个商业特性,需要付费许可证才能使用。但是,OpenJDK 也提供了一个开源的替代品,称为 JMC(Java Mission Control),可以用来监控和调优 Java 应用程序。

Java 15

递归式删除文件

rm -rf 哈哈哈 这个walk我怎么觉得跟python有点相似呀

新的 API,可以进行递归式的删除文件,包括目录和非空目录。这个 API 是通过 java.nio.file.Files 类的 delete(Path path) 方法来实现的,它可以删除指定路径下的文件或目录,并且可以递归删除目录中的所有子目录和文件。

下面是一个简单的示例,展示了如何使用这个 API 进行递归式删除文件:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class FileDeleter {
    public static void main(String[] args) throws IOException {
        Path directory = Paths.get("C:/temp");
        deleteDirectory(directory);
    }

    private static void deleteDirectory(Path directory) throws IOException {
        Files.walk(directory)
             .sorted((path1, path2) -> -path1.compareTo(path2))
             .forEach(path -> {
                 try {
                     Files.delete(path);
                 } catch (IOException e) {
                     System.err.printf("Failed to delete %s. %s", path, e.getMessage());
                 }
             });
    }
}

在这个示例中,定义了一个 FileDeleter 类,它包含一个 deleteDirectory 方法,该方法接受一个目录的路径,然后使用 Files.walk() 方法来递归遍历目录下的所有子目录和文件。使用 sorted() 方法按照反向顺序排序,确保删除子目录时,先删除子目录中的文件。最后使用 forEach() 方法来逐个删除目录下的所有文件和子目录,如果删除失败,则输出错误信息。

需要注意的是,递归删除文件可能会很慢,并且如果使用不当可能会意外删除重要文件,因此需要小心使用这个 API,确保正确地删除指定的文件和目录。

Java 16

静态成员类的上下文引用

对静态成员类进行了增强,可以在静态成员类中使用外部类的 this 引用,可以使得代码更加灵活和易读

本地变量类型推断升级

Java 14 引入了本地变量类型推断,可以使得代码更加简洁和易读。Java 16 对本地变量类型推断进行了升级,可以在更多的场景下使用

// 使用升级后的本地变量类型推断
var list = new ArrayList<String>();

使用本地变量类型推断可以使得代码更加简洁和易读,但是要注意遵循最佳实践和避免滥用类型推断。

Vector

Vector API,一种用于高性能数值计算的 API。Vector API 可以用来执行各种数值计算,例如矩阵乘法和傅里叶变换。

// 使用 Vector API 计算两个向量的点积
int[] a = {1, 2, 3, 4};
int[] b = {5, 6, 7, 8};
IntVector va = IntVector.fromArray(a, 0);
IntVector vb = IntVector.fromArray(b, 0);
int dotProduct = va.dotProduct(vb);
System.out.println(dotProduct);

使用 Vector API 可以提高数值计算的性能和效率,但是要注意避免使用过多的内存

Java 17

Records 类型增强

对 Records 类型进行了增强,可以更加灵活地定义 Records 类型。Records 类型现在可以有非 final 的字段和构造函数。

// 使用增强的 Records 类型
public record Person(String name, int age) {
    String fullName() {
        return name + " (" + age + ")";
    }
}

使用 Records 类型可以使得代码更加简洁和易读,但是要注意遵循最佳实践和避免滥用 Records 类型。

Sealed 类型

它可以用来限制一个类的子类,只有在预定义的一组类中才能被创建。这个特性可以增加代码的安全性、可维护性和可读性。

Sealed 类型可以通过在类声明中使用 sealed 关键字来定义,然后在这个类的子类中使用 permits 关键字来声明哪些子类可以被创建。需要注意的是,如果一个类被定义为 sealed 类型,那么它的所有子类必须是 final 类型或者是另一个 sealed 类型。

下面是一个简单的示例,展示了如何使用 Sealed 类型:

sealed interface Shape permits Circle, Rectangle {
    double area();
}

final class Circle implements Shape {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double area() {
        return Math.PI * radius * radius;
    }
}

final class Rectangle implements Shape {
    private final double width;
    private final double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double area() {
        return width * height;
    }
}

在这个示例中,定义了一个 Shape 接口,并使用 sealed 关键字声明它是一个 Sealed 类型,并使用 permits 关键字声明它只允许 Circle 和 Rectangle 类来实现这个接口。然后,定义了 Circle 和 Rectangle 两个类,它们都实现了 Shape 接口,并定义了它们的 area 方法来计算面积。

这个示例展示了如何使用 Sealed 类型来限制一个接口的实现类,并且可以方便地在编译期间检查出不符合要求的子类。这个特性可以帮助开发人员更好地管理类的继承关系,并提高代码的可读性和可维护性。

你可能感兴趣的:(java基础,java,jvm,开发语言)