都要Java 20了你还在玩Java 8?

共 8155字,需浏览 17分钟

 ·

2023-07-01 13:43

#01 Java版本演进  

        从第一个1995年发布的alpha和beta Java公开版本到即将发布的Java20, 已经有28个年头。这期间也发布了20多个版本,但其中被大家常用的也就几个版本,甚至现在好多应用还在用着Java8。

       在我们选择jdk版本的时候,尽量选择LTS(长期支持)版本,LTS 版本被认为是最稳定的版本,它经历了广泛的测试,并且大多包含了多年积累的改进。需要注意的是,LTS 版本的软件不一定涉及功能更新,除非有一个更新的 LTS 版本。但是,你会在 LTS 版本的更新中得到必要的错误修复和安全修复。

       Java 17, 11, 8 为目前提供支持的 LTS版本;Java 10 是上一个快速发布版本,且已不再被支持。2018年9月,随着 Java 11 的发布,Java 10 自当日起不再被支持。Oracle 将在 2019 年 1 月前为商业用途中的 Java 8 长期支持,而针对非商用的更新将继续提供,直至 2020 年 12 月;此外,AdoptOpenJDK 也为 Java 8 提供免费更新。针对 Java 11 的长期支持将不再由 Oracle 提供,而是改由 OpenJDK 社区提供,例如 Eclipse Adoptium(以前称之为 AdoptOpenJDK) 的 Eclipse Temurin。

e642e59b8f2fd2623a57a221c8a33167.webp


#02 JDK 17 工具

      Jdk中自带的工具可以给我们在代码开发和维护,性能调优等方面给予巨大的帮助,我们有必要了解一下jdk17中自带的一些开发运行工具。

2.1 所有平台

  • jar - 为类和资源创建存档,并从存档中操作或恢复单个类或资源

  • jarsigner - 签署并验证 Java 存档 (JAR) 文件

  • java - 启动 Java 应用程序

  • javac - 读取 Java 类和接口定义并将它们编译成字节码和类文件

  • javadoc - 从 Java 源文件生成 API 文档的 HTML 页面

  • javap - 反汇编一个或多个类文件

  • jcmd - 向正在运行的 Java 虚拟机 (JVM) 发送诊断命令请求

  • jconsole - 启动一个图形控制台来监视和管理 Java 应用程序

  • jdb - 查找和修复 Java 平台程序中的错误

  • jdeprscan - 扫描 jar 文件(或其他一些类文件的集合)以查找已弃用的 API 元素的静态分析工具

  • jdeps - 启动 Java 类依赖分析器

  • jfr - 解析和打印飞行记录器文件

  • jhsdb - 附加到 Java 进程或启动事后调试器以分析来自崩溃的 Java 虚拟机 (JVM) 的核心转储的内容

  • jinfo - 为指定的 Java 进程生成 Java 配置信息

  • jlink - 将一组模块及其依赖项组装并优化为自定义运行时映像

  • jmap - 打印指定进程的详细信息

  • jmod - 创建 JMOD 文件并列出现有 JMOD 文件的内容

  • jpackage - 打包一个独立的 Java 应用程序

  • jps - 列出目标系统上已检测的 JVM

  • jrunscript - 运行支持交互和批处理模式的命令行脚本外壳

  • jshell - 在读取-评估-打印循环 (REPL) 中交互式评估 Java 编程语言的声明、语句和表达式

  • jstack - 打印指定 Java 进程的 Java 线程的 Java 堆栈跟踪

  • jstat - 监控 JVM 统计信息

  • jstatd - 监控已检测的 Java HotSpot 虚拟机的创建和终止

  • keytool - 管理加密密钥、X.509 证书链和可信证书的密钥库(数据库)

  • rmid - 启动激活系统守护进程,使对象能够在 Java 虚拟机 (JVM) 中注册和激活

  • rmiregistry - 在当前主机的指定端口上创建并启动远程对象注册表

  • serialver - 以适合复制到进化类中的形式返回一个或多个类的“serialVersionUID”

2.2 仅适用于 Windows

  • jabswitch - 启用或禁用 Java Access Bridge

  • jaccessinspector - 使用 Java Accessibility Utilities API 检查有关 Java 虚拟机中对象的可访问信息

  • jaccesswalker - 浏览特定 Java 虚拟机中的组件树并在树视图中显示层次结构

  • javaw - 在没有控制台窗口的情况下启动 Java 应用程序

  • kinit - 获取并缓存 Kerberos 票证授予票证

  • klist - 显示本地凭证缓存和密钥表中的条目

  • ktab - 管理存储在本地密钥表中的主体名称和服务密钥


#03 从JDK8到JDK17的代码新特征

3.1 简洁的字符串函数

  • isBlank():如果字符串为空或字符串仅包含空格(包括制表符),则返回 true。注意与isEmpty() 不同,isEmpty()仅在长度为 0 时返回 true。
  • lines():将字符串拆分为字符串流,每个字符串包含一行。
  • strip() :分别从开头和结尾;
  • stripLeading()/stripTrailing()仅开始和仅结束删除空格。
  • repeat(int times):返回一个字符串,该字符串采用原始字符串并按指定的次数重复该字符串。
  • readString():允许从文件路径直接读取到字符串。
  • writeString(Path path):将字符串直接写入指定路径处的文件。
  • indent(int level):缩进字符串的指定量。负值只会影响前导空格。
  • transform(Function f):将给定的 lambda 应用于字符串。
      
        private void strFeatures() throws IOException {
      
      
                //lines()方法示例,\n \r可以换行
      
      
                String str = "Hello \njava17 \n!\r";
      
      
                Stream<String> lines = str.lines();
      
      
                lines.forEach(System.out::println);
      
      
        
          
//readString()方法示例 Path path = Path.of("D:\\good.txt"); String text = Files.readString(path).strip() ; System.out.println(text); }

3.2 字符串块

      
          private void textBlocks() {
      
      
                String textBlocks = """
      
      
                        {"name": "lisi", 
      
      
                         "age": %d, "sex": "%s"}
      
      
                         """.formatted(12, "男");
      
      
                System.out.println(textBlocks);
      
      
            }
      
    

3.3 record更简洁的类定义

   无需set/get方法和构造函数

      
        record User2(String name, Integer age) {
      
      
                @Override
      
      
                public String toString() {
      
      
                    return "User2[" +
      
      
                            "name='" + name + '\'' +
      
      
                            ", age=" + age +
      
      
                            ']';
      
      
                }
      
      
                @Override
      
      
                public boolean equals(Object obj) {
      
      
                    return false;
      
      
                }
      
      
                @Override
      
      
                public int hashCode() {
      
      
                    return 0;
      
      
                }
      
      
            }
      
    

3.4 简单的switch表达式

      
          private  void newSwitch() {
      
      
                int size = 3;
      
      
                String cn = switch (size) {
      
      
                    case 1 -> "一";
      
      
                    case 2 -> "二";
      
      
                    case 3 -> "三";
      
      
                    default -> "未知";
      
      
                };
      
      
                System.out.println(cn);
      
      
            }
      
    

3.5 密封类

      
        /**
      
      
          * 定义一个抽象密封类Vehicle ,它的实现类只能是Car , Bus这两个,
      
      
          * 其他的实现类均不允许
      
      
          */
      
      
        public abstract sealed class Vehicle permits Car, Bus {}
      
      
        public final class Car extends Vehicle {
      
      
        }
      
      
        public final class Bus extends Vehicle{
      
      
        }
      
    

3.6   Vector 向量计算

      Vector 向量计算 API 是为了处理 SIMD(Single Instruction Multiple Data,单指令多数据)类型的操作,即并行执行的各种指令集。它利用支持向量指令的专用 CPU 硬件,并允许以管道的形式执行此类指令。这种运算方式可以让开发人员实现更高效的代码,充分利用底层硬件的潜力。日常使用包括科学代数线性应用程序、图像处理、字符处理、繁重的算术应用程序,以及任何需要对多个独立操作数应用一个运算的应用程序。  Vector 向量计算 API 是在 Java16 引入(参见 Java16 的新特性),可以在运行时借助 CPU 向量运算指令,实现更优的计算能力。在 Java17 中,针对性能和实现进行了改进,包括字节向量与布尔数组之间进行转换。

      
           private void vectorCalc(){
      
      
                final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
      
      
                final float[] a = {1, 2, 3, 4};
      
      
                final float[] b = {5, 6, 7, 8};
      
      
                final float[] c = new float[3];
      
      
                for (var i = 0; i < a.length; i += SPECIES.length()) {
      
      
                    var m = SPECIES.indexInRange(i, a.length);
      
      
                    var va = FloatVector.fromArray(SPECIES, a, i, m);
      
      
                    var vb = FloatVector.fromArray(SPECIES, b, i, m);
      
      
                    var vc = va.mul(vb);
      
      
                    vc.intoArray(c, i, m);
      
      
               }
      
      
            }
      
    


    
浏览 329
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报