文章目录

  • 写在前面
  • 1、JDK17的安装与java环境变量
    • 1.1、第一种:把jdk1.8更换为jdk17
    • 1.2、第二种jdk1.8与jdk17并存
  • 2、SpringBoot 3.0尝鲜
    • 2.1、pom.xml
    • 2.2、启动类
    • 2.3、idea中可能需要你配置的内容
  • 3、新特性
    • 3.1、java 9 新增
    • 3.2、java 10 新增
    • 3.3、java 11 新增
    • 3.4、java 12 新增
    • 3.5、java 13 新增
    • 3.6、java 14 新增
    • 3.7、java 15 新增
    • 3.8、java 16 新增
    • 3.9、java 17 新增

写在前面

从jdk8升级到jdk17,会遇到哪些问题?

1、JDK17的安装与java环境变量

首先从官网上下载一个JDK17的包,windows系统可能有这两种包(压缩包和安装包)

https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html

这里我们以压缩包为例,下载完直接解压,放到一个非中文路径下(复制这个路径)


接下有两种使用JDK17的方式:

1.1、第一种:把jdk1.8更换为jdk17

接下来找到系统环境变量,把JAVA_HOME变成JDK17的路径

1.2、第二种jdk1.8与jdk17并存

如果你只是想尝尝鲜,那么不建议你把环境变量改为jdk17。你只需解压jdk17后,在对应的编码工具里面添加jdk17,例如这里,我在idea中添加JDK17

2、SpringBoot 3.0尝鲜

SpringBoot 3.0最低使用jdk17、maven3.5

2.1、pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.0-M4</version><relativePath/></parent><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><name>demo</name><description>springboot3-mavenDemo</description><properties><!--Jdk版本要求17以上--><java.version>17</java.version></properties><dependencies><!--引入spring-boot-starter-web,支持web开发--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><!--spring boot maven插件,支持maven的全流程命令以及程序运行--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><!--由于目前3.0还是处于里程碑版本,等到正式release版本,此配置不需要--><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories></project>

2.2、启动类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}}

有这两个文件你就可以尝试启动了

2.3、idea中可能需要你配置的内容

1、设置中的ava编译器

2、项目结构中的设置

3、新特性

本文提到的新特性主要侧重于代码结构与API上

3.1、java 9 新增

1、module-info.java:该文件必须位于项目的根目录中。该文件用于定义模块需要什么依赖,以及那些包被外部使用。

2、jshell:jshell工具提供了一个交互式命令界面,可以评估声明,语句和表达式,无需编译即可返回执行结果。


3、接口的私有方法

public interface MyInterface {void normalInterfaceMethod();default void defaultMethod1(){privateMethod();}default void defaultMethod2(){privateMethod();}//接口的私有方法可以在JDK9中使用private void privateMethod(){System.out.println("这是一个接口的私有方法");}
}

4、资源自动关闭

InputStreamReader reader = new InputStreamReader(System.in);
OutputStreamWriter writer = new OutputStreamWriter(System.out);
//多资源用分号隔开
try (reader;writer) {//......
} catch (IOException e) {e.printStackTrace();
}
// reader和writer会自动关闭

5、可以在匿名实现类中重写方法等操作

Set<String> set = new HashSet<>(){//匿名实现类重写add方法。@Overridepublic boolean add(String s) {System.out.println("执行add方法");return super.add(s);}
};
set.add("1");

6、String 存储结构变更

JDK9将String底层存储数据改为byte数组,StringBuffer和StringBuilder也同样做了变更,将以往char数组改为byte数组。

7、使用of方法直接快速创建只读集合

List<String> list = List.of("A", "B", "C");
List<String> copy = List.copyOf(list);
System.out.println(list == copy); // trueList<String> list1 = new ArrayList<String>();
List<String> copy1 = List.copyOf(list1);
System.out.println(list1 == copy1); // false,非of方法创建的copyOf->false

8、增强 Stream API,Stream接口中新增4个方法:dropWhile、takeWhile、ofNullable,为iterate方法新增重载方法。

List<Integer> list = Arrays.asList(45,43,76,87,42,77,90,73,67,88);
list.stream().takeWhile((x) -> x < 80 ).forEach(System.out::println);// 返回结果
// 45
// 43
// 76

9、改进 Optional 类,主要是新增了三个方法:stream,ifPresentOrElse 和 or 。

List<String> list = List.of("A", "B", "C", "D", "E", "F");
Optional<List<String>> optional = Optional.of(list);
optional.stream().forEach(System.out::println);

10、多分辨率图像 API,在 java.awt.image 包下新增了支持多分辨率图片的API,用于支持多分辨率的图片。
11、支持HTTP2,全新的 HTTP 客户端 API 可以从 jdk.incubator.httpclient 模块中获取。因为在默认情况下,这个模块是不能根据 classpath 获取的,需要使用 add modules 命令选项配置这个模块,将这个模块添加到 classpath中。
12、其他

3.2、java 10 新增

1、可以使用var作为局部变量类型推断标识符,仅适用于局部变量

var str = "ABC"; //根据推断为 字符串类型
var l = 10L;//根据10L 推断long 类型
var flag = true;//根据 true推断 boolean 类型
var flag1 = 1;//这里会推断boolean类型。0表示false 非0表示true
var list = new ArrayList<String>();  // 推断 ArrayList<String>
var stream = list.stream();          // 推断 Stream<String>
//错误的用法
var error;//×

2、其他:将JDK多存储库合并为单存储库、垃圾回收接口、并行Full GC 的G1、应用数据共享、线程局部管控等。

3.3、java 11 新增

1、在Lambda表达式中,可以使用var关键字来标识变量,变量类型由编译器自行推断。

        Arrays.asList("Java", "Python", "Ruby").forEach((var s) -> {System.out.println("Hello, " + s);});

2、字符串加强

// 判断字符串是否为空白
" ".isBlank(); // true
// 去除首尾空格
" Javastack ".strip(); // "Javastack"
// 去除尾部空格
" Javastack ".stripTrailing(); // " Javastack"
// 去除首部空格
" Javastack ".stripLeading(); // "Javastack "
// 复制字符串
"Java".repeat(3);// "JavaJavaJava"
// 行数统计
"A\nB\nC".lines().count(); // 3

3、InputStream 加强,transferTo,可以用来将数据直接传输到 OutputStream

var classLoader = ClassLoader.getSystemClassLoader();
var inputStream = classLoader.getResourceAsStream("javastack.txt");
var javastack = File.createTempFile("javastack2", "txt");
try (var outputStream = new FileOutputStream(javastack)) {inputStream.transferTo(outputStream);
}

4、HTTP Client API

var request = HttpRequest.newBuilder()
.uri(URI.create("https://javastack.cn"))
.GET()
.build();
var client = HttpClient.newHttpClient();
// 同步
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// 异步
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);

5、对Files类增加了writeString和readString两个静态方法

Files.writeString(Path.of("./", "tmp.txt"), // 路径"hello, jdk11 files api", // 内容StandardCharsets.UTF_8); // 编码
String s = Files.readString(Paths.get("./tmp.txt"), // 路径StandardCharsets.UTF_8); // 编码

6、一个文件中可以包含多个public类
7、Shebang文件,Shebang文件是Unix系统中常见的文件,以#!/path/to/executable作为文件的开头第一行,可以作为脚本小程序直接运行一段代码。

#!/g/jdk-11/bin/java --source 11public class SimpleInterest{public static void main(String[] args){if ( args == null || args.length < 3 ){System.err.println("Three arguments required: principal, rate, period");System.exit(1);}int principal = Integer.parseInt(args[0]);int rate = Integer.parseInt(args[1]);int period = Integer.parseInt(args[2]);double interest = Maths.simpleInterest(principal, rate, period);System.out.print("Simple Interest is: " + interest);}
}public class Maths{public static double simpleInterest(int principal, int rate, int period){if ( rate > 100 ){System.err.println("Rate of interest should be <= 100. But given values is " + rate);System.exit(1);}return ( principal * rate * period * 1.0 ) / 100;}
}

3.4、java 12 新增

1、Switch扩展了

switch (day) {case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);case TUESDAY                -> System.out.println(7);case THURSDAY, SATURDAY     -> System.out.println(8);case WEDNESDAY              -> System.out.println(9);
}int numLetters = switch (day) {case MONDAY, FRIDAY, SUNDAY -> 6;case TUESDAY                -> 7;case THURSDAY, SATURDAY     -> 8;case WEDNESDAY              -> 9;
};

2、String类中新增transform()和indent()
3、Files类中新增mismatch()
4、支持unicode11和压缩数字格式化

        var cnf = NumberFormat.getCompactNumberInstance(Locale.CHINA, NumberFormat.Style.SHORT);System.out.println(cnf.format(1_0000));System.out.println(cnf.format(1_9200));System.out.println(cnf.format(1_000_000));System.out.println(cnf.format(1L<<30));System.out.println(cnf.format(1L<<40));System.out.println(cnf.format(1L<<50));//1万//2万//100万//11亿//1兆//1126兆

5、其他:JVM Constants API、默认CDS存档、可中断的G1 Mixed GC等

3.5、java 13 新增

1、NioSocketImpl替换了PlainSocketImpl

public class HelloApp {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888)) {boolean running = true;System.out.println("listened 8888");while (running) {Socket clientSocket = serverSocket.accept();//do something with clientSocket}} catch (IOException e) {e.printStackTrace();}}
}

2、新的关键字yield用于返回switch语句的内容

// 没有逻辑的返回
int numLetters = switch (day) {case MONDAY, FRIDAY, SUNDAY -> 6;case TUESDAY                -> 7;case THURSDAY, SATURDAY     -> 8;case WEDNESDAY              -> 9;
};// 逻辑较多的处理String result = switch (number) {case 1, 2:// 逻辑代码yield "one or two";case 3:// 逻辑代码yield "three";case 4, 5, 6:yield "four or five or six";default:yield "unknown";};return result;

3、添加了“”“ 长文本内容 ”“”

开头"““之后必须另起一行,另外结尾的””"是否另起一行有不同的效果

String html = """<html><body><p>Hello, world</p></body></html>""";

3.6、java 14 新增

1、类型匹配instanceof增强

Object obj = "kuaidi100";
if(obj instanceof String str){//直接使用str
}

2、数据载体的类型 record

record默认为final的,成员变量也为final,所以没有set方法。在JDK15中对它进行了继续加强。

public record Kuaidi100Record(@Name("name") int x, int y) {public static String one;
}

3、其他:移除CMS垃圾收集器、ZGC支持windows,macOS等

3.7、java 15 新增

1、新加入 Edwards-Curve 数字签名算法(EdDSA)实现加密签名。

// example: generate a key pair and sign
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Ed25519");
KeyPair kp = kpg.generateKeyPair();
// algorithm is pure Ed25519
Signature sig = Signature.getInstance("Ed25519");
sig.initSign(kp.getPrivate());
sig.update(msg);
byte[] s = sig.sign();// example: use KeyFactory to contruct a public key
KeyFactory kf = KeyFactory.getInstance("EdDSA");
boolean xOdd = ...
BigInteger y = ...
NamedParameterSpec paramSpec = new NamedParameterSpec("Ed25519");
EdECPublicKeySpec pubSpec = new EdECPublicKeySpec(paramSpec, new EdPoint(xOdd, y));
PublicKey pubKey = kf.generatePublic(pubSpec);

2、封闭类sealed,有了这个特性,意味着以后不是你想继承就继承,想实现就实现了,你得经过允许才行。

public abstract sealed class Studentpermits ZhangSan, LiSi, ZhaoLiu {...}

3、隐藏类

// 一个普通类
public class JEP371HiddenClasses {public static String hello() {return "https://www.didispace.com";}
}// 隐藏类
String filePath = "JEP371HiddenClasses.class";
byte[] b = Files.readAllBytes(Paths.get(filePath));
log.info(Base64.getEncoder().encodeToString(b));// 最终打印(这就是个隐藏类)
yv66vgAAAD0AFAoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCAAIAQAZaHR0cHM6Ly93d3cuZGlkaXNwYWNlLmNvbQcACgEALmNvbS9kaWRpc3BhY2UvZGVidWcvamF2YTE1L0pFUDM3MUhpZGRlbkNsYXNzZXMBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAMExjb20vZGlkaXNwYWNlL2RlYnVnL2phdmExNS9KRVAzNzFIaWRkZW5DbGFzc2VzOwEABWhlbGxvAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAApTb3VyY2VGaWxlAQAYSkVQMzcxSGlkZGVuQ2xhc3Nlcy5qYXZhACEACQACAAAAAAACAAEABQAGAAEACwAAAC8AAQABAAAABSq3AAGxAAAAAgAMAAAABgABAAAAAwANAAAADAABAAAABQAOAA8AAAAJABAAEQABAAsAAAAbAAEAAAAAAAMSB7AAAAABAAwAAAAGAAEAAAAGAAEAEgAAAAIAEw==// 使用隐藏类
void testHiddenClasses() throws Throwable {// 1. 加载encode之后的隐藏类String CLASS_INFO = "yv66vgAAAD0AFAoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCAAIAQAZaHR0cHM6Ly93d3cuZGlkaXNwYWNlLmNvbQcACgEALmNvbS9kaWRpc3BhY2UvZGVidWcvamF2YTE1L0pFUDM3MUhpZGRlbkNsYXNzZXMBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAMExjb20vZGlkaXNwYWNlL2RlYnVnL2phdmExNS9KRVAzNzFIaWRkZW5DbGFzc2VzOwEABWhlbGxvAQAUKClMamF2YS9sYW5nL1N0cmluZzsBAApTb3VyY2VGaWxlAQAYSkVQMzcxSGlkZGVuQ2xhc3Nlcy5qYXZhACEACQACAAAAAAACAAEABQAGAAEACwAAAC8AAQABAAAABSq3AAGxAAAAAgAMAAAABgABAAAAAwANAAAADAABAAAABQAOAA8AAAAJABAAEQABAAsAAAAbAAEAAAAAAAMSB7AAAAABAAwAAAAGAAEAAAAGAAEAEgAAAAIAEw==";byte[] classInBytes = getDecoder().decode(CLASS_INFO);Class<?> proxy = MethodHandles.lookup().defineHiddenClass(classInBytes, true, MethodHandles.Lookup.ClassOption.NESTMATE).lookupClass();// 输出类名log.info(proxy.getName());// 输出类有哪些函数for(Method method : proxy.getDeclaredMethods()) {log.info(method.getName());}// 2. 调用hello函数MethodHandle mh = MethodHandles.lookup().findStatic(proxy, "hello", MethodType.methodType(String.class));String result = (String) mh.invokeExact();log.info(result);
}

4、其他

3.8、java 16 新增

1、主要是java10到15中的预览功能转正。
2、其他:可弹性伸缩的元数据区、 新的打包工具jpackage、针对Value-Based类的编译器warning提示、提供向量计算的API、提供操作外部内存的能力等

3.9、java 17 新增

1、正式引入密封类sealed class,限制抽象类的实现;
2、统一日志异步刷新,先将日志写入缓存,然后再异步刷新;
3、其他:特定于上下文的反序列化过滤器、弃用 Applet API 以进行删除、增强型伪随机数生成器、恢复始终严格的浮点语义

从jdk8升级到jdk17相关推荐

  1. jdk8升级成jdk17报错 module java.base does not “opens java.lang“ to unnamed module @1941a8ff

    jdk9+ 出现错误 module java.base does not "opens java.lang" to unnamed module @1941a8ff 在启动类配置中 ...

  2. JDK8升级JDK9 HTT2 TLS问题解决之路(艰辛)

    背景描述 s公告服务是雪球行情的公告抓取服务,主要负责从相关网站抓取A股.港股.美股公告,调用接口发贴.数据抓取是在该业务场景是行情数据的入口,影响以后的的处理逻辑.因此,通过代理池+proxy的方式 ...

  3. Java 8 要过时了?从JDK8飞升到JDK17,一次性给你讲明白

    背景 2022年Spring6和 SpringBoot3相继推出,在此之前,Java社区一直是"新版任你发,我用Java 8",不管新版本怎么出,很少有人愿意升级. 这一次,Spr ...

  4. spring版本 jdk8_从JDK8升级到JDK11,看这篇就足够了

    原文地址:https://blog.codefx.org/java/java-11-migration-guide/. 在原文的基础上,增加了一些我遇到的具体的坑还有在特定场景下的解决方案,供大家参考 ...

  5. JDK11变化详解JDK8升级JDK11详细指南

    原文链接:https://yq.aliyun.com/articles/659407 官方英文原版: https://docs.oracle.com/en/java/javase/11/migrate ...

  6. JDK11变化详解,JDK8升级JDK11详细指南

    为什么80%的码农都做不了架构师?>>>    官方英文原版: https://docs.oracle.com/en/java/javase/11/migrate/index.htm ...

  7. ​windows10 jdk8升级到11后环境变量配置不生效

    一.问题 以前安装过安装版的jdk后,配置过环境变量,然后现在更换jdk版本且修改环境变量并不能生效,如原本安装了1.8,现更换为11,且配置了环境变量,但是java -version仍显示1.8. ...

  8. 从JDK8到JDK17,需要注意的一些新特性

    这篇文章并非单一的介绍JDK17的新特性,而是将jdk8到jdk17之间所有新加入的特性进行了简单的汇总,罗列一系列重要的改动,以便从JDK8升级到JDK17. 模块化开发 这并非jdk17的新特性, ...

  9. openJDK 官方二进制下载

    前言 由于Oracle的jdk收费license,JDK8 201~221开始不免费了,目前有最近的JDK17 LTS明确免费了,但是不确定什么时候会修改协议,而且升级jdk也不能从jdk8升级到jd ...

最新文章

  1. linux vim 高级,Vim命令高级用法
  2. 产权分割商铺,太坑人!
  3. 标签view文字自动换行
  4. jmeter响应数据Unicode编码转换为汉字
  5. matlab中(1 )什么意思,matlab中area(1)什么意?mat – 手机爱问
  6. css布局左右2边固定,中间自适应
  7. mos管防倒灌电路_MOS管自举电路工作原理及升压自举电路结构图
  8. 希尔排序--Java
  9. 配置vivado用vscode编辑文本
  10. CentOS 7中将Tomcat设置为系统服务
  11. List集合之LinkedList
  12. osgb转3dtiles 原理_自动控制原理实验箱无法通行故障维修
  13. html+div+css+jquery+javascript的关系
  14. 桌面打不开计算机控制面板,右键桌面nvidia控制面板打不开的解决方法 - 系统家园...
  15. 【神科普】诺基亚:你以为它死了,其实它已重回世界第二
  16. 操作 神通数据库_神通大型通用数据库
  17. 计算机初始《wps表格》教案,wps教案
  18. MMC-HVDC仿真模型,pscad柔性直流输电仿真mmc仿真模型,双端mmc模型,MMC为21电平NLM和均压控制
  19. MQTT自定义透传_DTU连接阿里云
  20. BrowserslistError: Unknown version 67 of android

热门文章

  1. 目标检测带标签数据增强代码
  2. 蚂蚁与大象共舞?DeFi 如何选择更完美的链上治理
  3. ACCESS 2003数据库的创建
  4. mac App Store下载出现“未知错误”可能原因及解决办法
  5. Python项目容器化实践 - 编排方案: Mesos+Marathon
  6. Vue SEO的四种方案
  7. Redisson 3.7.x 版本报非法反射:WARNING: An illegal reflective access operation has occurred
  8. Tomcat文件夹目录
  9. 小米耳机处于可配对模式_坚果上架Smartisan真无线耳机
  10. 云计算机不支持加密狗,电脑两个用户名会不会造成加密狗不能识别?