特性差异浅析-JDK11-JDK17-与 (特性差异浅析方法)
1.1switch表白式语法变动
publicclassDemo{publicstaticvoidmn(String[]args){varscore='C';//执行switch分支语句Strings=switch(score){case'A','B'->"上等";case'C'->"中等";case'D','E'->"上等";default->{if(score>100){yield"数据不能超越100";}else{yieldscore+"此分数低于0分";}}}}}
1.2微基准测试套件
JMH,即JavaMicrobenchmarkHarness,是专门用于代码微基准测试的工具套件。
JMH典型的运行场景
JMH经常使用案例
参与JMH的依赖
<properties><jmh.version>1.14.1</jmh.version></properties><dependencies><dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-core</artifactId><version>${jmh.version}</version></dependency><dependency><groupId>org.openjdk.jmh</groupId><artifactId>jmh-generator-annprocess</artifactId><version>${jmh.version}</version><scope>provided</scope></dependency></dependencies>
![与](https://tyye.cn/zb_users/theme/tpure/style/images/lazyload.png)
代码编写
importorg.openjdk.jmh.annotations.*;@State(Scope.Thread)publicclassMyBenchmark{@Benchmark@BenchmarkMode(Mode.All)publicvoidtestMethod(){try{Thread.sleep(300);}catch(InterruptedExceptione){e.printStackTrace();}}@Benchmark@BenchmarkMode(Mode.All)publicvoidtestMethod2(){try{Thread.sleep(600);}catch(InterruptedExceptione){e.printStackTrace();}}}
importorg.openjdk.jmh.runner.Runner;importorg.openjdk.jmh.runner.options.Options;importorg.openjdk.jmh.runner.options.OptionsBuilder;publicclassBenchmarkRunner{publicstaticvoidmain(String[]args)throwsException{Optionsopt=newOptionsBuilder().include(MyBenchmark.class.getSimpleName()).forks(1).warmupIterations(5).measurementIterations(5).build();newRunner(opt).run();}}//以下这些方法都是JMH的一局部,可以在任何版本的JMH中经常使用。//include(SimpleBenchmark.class.getSimpleName()):这个方法示意你想要运转哪个类的基准测试。//exclude("xxx"):这个方法示意你想要在基准测试中扫除哪个方法。//forks(1):这个方法示意你想要启动多少轮的基准测试。每一轮测试都会在一个新的JVM进程中启动,以确保每轮测试的环境是独立的。//warmupIterations(5):这个方法示意你想要启动多少次预热迭代。预热迭代是为了让JVM到达稳固形态,预热迭代的结果不会被计入最终的基准测试结果。//measurementIterations(5):这个方法示意你想要启动多少次正式的基准测试迭代,这些迭代的结果会被用来计算基准测试的最终结果。
结果输入(只截取了一局部)
图片
图片
相关注解
@BenchmarkMode
对应Mode选项,可用于类或许方法上,须要留意的是,这个注解的value是一个数组,可以把几种Mode汇合在一同执行,还可以设置为Mode.All,即所有执行一遍。
图片
类注解,JMH测试类必定经常使用@State注解,State定义了一个类实例的生命周期,可以类比SpringBean的Scope。由于JMH准许多线程同时执行测试,不同的选项含意如下:
Scope.Thread:自动的State,每个测试线程调配一个实例。
Scope.Benchmark:一切测试线程共享一个实例,用于测试有形态实例在多线程共享下的性能。
Scope.Group:每个线程组共享一个实例。
假设你想测试一个对象在多线程环境下的行为,你可以选用Scope.Benchmark。假设你想要每个线程都有自己的形态,你可以选用Scope.Thread。假设你想要在同一线程组内的一切线程共享形态,你可以选用Scope.Group。
@OutputTimeUnit
benchmark结果所经常使用的期间单位,可用于类或许方法注解,经常使用java.util.concurrent.TimeUnit中的规范期间单位。
@Benchmark
方法注解,示意该方法是须要启动benchmark的对象。
1.3生成类数据共享特性优化
背景:在同一个物理机上启动多个JVM时,假设每个虚构机都独自装载自己须要的一切类,启动老本和内存占用是比拟高的。所以引入了类数据共享机制(Class>
1.5ShenandoahGC
参与一个名为Shenandoah的新渣滓搜集算法,经过与正在运转的Java线程同时启动疏散上班来缩小GC暂停期间,最终指标旨在针对JVM上的内存收回成功低进度的需求。
Shenandoah是以试验特性在JDK12中引入的。在JDK15中正式上线。
经常使用Shenandoah的暂停期间与堆大小有关,这象征着无论堆是200MB还是200GB,都将具备相反的分歧暂停期间。与ZGC相似,ShenandoahGC关键指标是99.9%的暂停小于10ms,暂停与堆大小有关等。
ZGC和ShenandoahGC的一些关键区别:
经常使用方法:要启用/经常使用ShenandoahGC,须要以下JVM选项:-XX:+UnlockExperimentalVMOptions-XX:+UseShenandoahGC。作为试验性性能,Shenandoah构建系统会智能禁用不受支持的性能。
1.6String新增方法
varrs="test".transform(s->s+"Java").transform(s->s.toUpperCase());//TESTJAVA
Stringresult="Javanjavantest".indent(3);/*结果会缩进三格Javajavatest*/
1.7Files新增mismatch方法
前往内容第一次性不婚配的字符位置索引。
System.out.println(Files.mismatch(Path.of("a.txt"),Path.of("b.txt")));
1.8外围库java.text支持紧缩数字格局
NumberFormat参与了对紧凑方式格局化数字的支持。
紧凑数字格局是指以冗长或人类可读方式示意的数字。
例如,在en_US言语环境中,1000可以格局化为1K,1000000可以格局化为1M,详细取决于指定的样式NumberFormat.Style。紧凑数字格局由LDML的CompactNumber格局规范定义。要失掉实例,请经常使用NumberFormat紧凑数字格局所给出的工厂方法之一。
NumberFormatfmt=NumberFormat.getCompactNumberInstance(Locale.US,NumberFormat.Style.SHORT);Stringresult=fmt.format(1000);//1Kvarcnf=NumberFormat.getCompactNumberInstance(Locale.CHINA,NumberFormat.Style.SHORT);System.out.println(cnf.format(5_0000));//"5万"System.out.println(cnf.format(7_9200));//"7.9万"System.out.println(cnf.format(8_000_000));//"800万"System.out.println(cnf.format(9L<<30));//"96亿"System.out.println(cnf.format(6L<<50));//"5637142兆"System.out.println(cnf.format(6L<<60));//"6917529京"
1.9JDK17支持到Unicode13
JDK12支持Unicode11.0
JDK13支持Unicode12.1
从JDK14到JDK17均是支持Unicode13.0
1.10NullPointerExceptions更新
JDK14之前,从报错中咱们只能失掉失误发生的行数,但在JDK14之后,会明晰的通知你哪个对象空指针了。
Exceptioninthread"main"java.lang.NullPointerException:Cannotinvoke"String.charAt(int)"because"str"isnullatcom.qf.jdk14.Test.main(Test.java:11)
1.11文本块特性
背景:在Java中,在字符串文字中嵌入,XML,SQL或JSON片段通常须要先启动转义和串联的少量编辑,而后才干编译蕴含该片段的代码。该代码段通常难以浏览且难以保养。
Java的文本块特性是在JDK15中正式成功的。这个特性首先在JDK13中以预览版的方式颁布,而后在JDK14中改良并再次以预览版的方式颁布。这一特性提高了Java程序书写大段字符串文本的可读性和繁难性。
文本块的扫尾定界符是由三个双引号"""开局,重新的一行开局字符串的内容,以"""完结。假设完结的"""另起一行时,字符串内容最后会留有一新行。
经常使用案例
Stringquery="SELECT`EMP_ID`,`LAST_NAME`FROM`EMPLOYEE_TB`n"+"WHERE`CITY`='INDIANAPOLIS'n"+"ORDERBY`ID`,`LAST_NAME`;";//经常使用文本块语法Stringquery="""SELECT`EMP_ID`,`LAST_NAME`FROM`EMPLOYEE_TB`WHERE`CITY`='INDIANAPOLIS'ORDERBY`EMP_ID`,`LAST_NAME`;""";
Stringhtml="<html>n"+"<body>n"+"<p>Hello,world</p>n"+"</body>n"+"</html>n";//经常使用文本块语法Stringhtml="""<html><body><p>Hello,world</p></body></html>""";
缩进示例
Java编译器会智能删除不须要的缩进:
System.out.println("""Hello,multilinetextblocks!""");//结果//>Hello,//>multiline//>textblocks!
1.12重新成功旧版SocketAPI
背景:如今已有的java.Socket和java.net.ServerSocket以及它们的成功类,都可以回溯到JDK1.0时代了。原始socket的保养和调试都很痛苦。成功类还经常使用了线程栈作为I/O的缓冲,造成在某些状况下还须要参与线程栈的大小。该成功还存在几个并发疑问,须要彻底处置。在未来的网络环球,要极速照应,不能阻塞本中央法线程,以后的成功不适宜经常使用了。
JDK13全新成功的NocketImpl来交流JDK1的SocketImpl和PlainSocketImpl。
1.13HiddenClasses
通常咱们在经常使用大型的框架或许lambda表白式的时刻,会灵活生成很多类。然而可怜的是规范的定义类的API:ClassLoader::defineClass和Lookup::defineClass不能够辨别出这些类是灵活生成(运转时生成)的还是静态生成(编译生成)的。
普通来说灵活生成的类生命周期更短,并且其可⻅性要更低。然而现有的JDK并没有这特性能。
一切有了HiddenClasses的提案,经过HiddenClasses,不论是JDK还是JDK外部的框架,在生成灵活类的时刻都可以定义为HiddenClasses,这样可以愈加有效的控制这些灵活生成类的生命周期和可⻅性。
1.14instanceof关键词
instanceof关键词关键用来判别某个对象是不是某个类的实例。
比如,有时刻咱们要处置一个相似这样的数据集:
Map<String,Object>>Objectvalue=>Objectvalue=>publicfinalclassUser{finalStringname;finalintage;publicUser(Stringname,intage){this.name=name;this.age=age;}@OverridepublicStringtoString(){return"User{"+"name='"+name+'''+",}';}@Overridepublicbooleanequals(Objecto){if(this==o)returntrue;if(o==null||getClass()!=o.getClass())returnfalse;Useruser=(User)o;returnage==user.age&&Objects.equals(name,user.name);}@OverridepublicinthashCode(){returnObjects.hash(name,age);}}
经过Record类方式,一句话就可以成功以上性能,代码如下:
publicrecordUser(Stringusername,Stringpass){}
在JDK16之前的版本中,咱们不能在类名前面间接写参数来定义类的形态。这是JDK16引入record类的一个新特性。
调用Record类方式,如下:
publicclass{publicstaticvoidmain(String[]args){Useruser=newUser("user","123456");System.out.println(user.username());}}
留意事项:
1.16密封类
在JDK15中,Java提出了密封类(SealedClasses)的概念,在JDK17中被正式确认。密封类准许类和接口定义其准许的子类型。因此,假设一个类没有显式地经常使用sealed、non-sealed或final关键字,那么它的自动权限就是non-sealed。
以下是一个密封类的代码示例:
sealedclassHumanpermitsKyrie,LeBron,George{publicvoidprintName(){System.out.println("Default");}}non-sealedclassKyrieextendsHuman{publicvoidprintName(){System.out.println("Bob");}}sealedclassLeBronextendsHuman{publicvoidprintName(){System.out.println("Mike");}}finalclassGeorgeextendsHuman{publicvoidprintName(){System.out.println("Yannick");}}
在这个例子中,Human是一个密封类,它只准许Kyrie,LeBron和George这三个类承袭。这样,咱们就可以更准确地控制哪些类可以承袭Human类,从而提高代码的安保性和可读性。
1.17一致日志异步刷新
在JDK17中,引入了一项新特性:一致日志异步刷新。
先将日志写入缓存,而后再异步地刷新到日志文件,这样写日志的操作就不会阻塞执行业务逻辑的线程,从而提高了程序的运转效率。这个特性关于须要少量日志输入,并且对性能有较高要求的运行来说,是一个十分适用的改良。可以经过传递命令行选项-Xlog:async来开启此性能。
总结
从JDK11到JDK17,Java的开展教训了一系列关键的里程碑。其中最关键的是JDK17的颁布,这是一个常年支持(LTS)版本,它将取得常年的更新和支持,有助于坚持程序的稳固性和牢靠性。此外,Java的性能也有了清楚的优化。这些提高都反映了Java在继续改良和顺应现代编程需求方面的承诺。
参考文档
上课要求jdk版本1.8.0而我的版本是jdk11,有什么区别
jdk版本迭代都是根据上一代进行增添新功能。djk11在1.8版本上只是添加了少许新内容以适应现在互联网du技术节奏,除了新添加的内容,两者没有什么影响。也就是,如果不用到新添加的内容,运行不受影响。但是需要知道,有哪些内容是新的。
JDK1.8的新特性:
一、接口的默认方法Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法。
二、Lambda 表达式在Java 8 中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:
(names, (String a, String b) -> {return (a);});
三、函数式接口Lambda表达式是如何在java的类型系统中表示的,每一个lambda表达式都对应一个类型,通常是接口类型。
而“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。因为默认方法不算抽象方法,所以也可以函数式接口添加默认方法。 四、方法与构造函数引用Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用,上面的代码展示了如何引用一个静态方法,我们也可以引用一个对象的方法:
converter = something::startsWith;
String converted = (Java);
(converted);
五、Lambda 作用域在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。
六、访问局部变量可以直接在lambda表达式中访问外层的局部变量:
七、访问对象字段与静态变量 和本地变量不同的是,lambda内部对于实例的字段以及静态变量是即可读又可写。该行为和匿名对象是一致的:
八、访问接口的默认方法JDK 1.8 API包含了很多内建的函数式接口,在老Java中常用到的比如Comparator或者Runnable接口,这些接口都增加了@FunctionalInterface注解以便能用在lambda上。
Java 8 API同样还提供了很多全新的函数式接口来让工作更加方便,有一些接口是来自Google Guava库里的,即便你对这些很熟悉了,还是有必要看看这些是如何扩展到lambda上使用的。
扩展资料:
jdk11新特性:
1、字符串加强
// 判断字符串是否为空白 (); // true// 去除首尾空格 Javastack (); // Javastack// 去除尾部空格 Javastack ()。
// 去除首部空格 Javastack (); // Javastack // 复制字符串(3); // JavaJavaJava// 行数统计A\nB\()(); // 3
2、HttClient Api
这是 Java 9 开始引入的一个处理 HTTP 请求的的孵化 HTTP Client API,该 API 支持同步和异步,而在 Java 11 中已经为正式可用状态,你可以在包中找到这个 Api
3、用于 Lambda 参数的局部变量语法
用于 Lambda 参数的局部变量语法简单来说就是支持类型推导:
var x = new A();for (var x : xs) { ... }try (var x = ...) { ... } catch ...
从JDK 9开始,JDK使用G1作为默认的废品回收器。G1可以说是GC的一个里程碑,G1之前的GC回收,还是基于固定的内存区域,而G1采用了一种“细粒度”的内存管理策略,不在固定的区分内存区域属于surviors、eden、old。
而我们不需要再去对于年轻代使用一种回收策略,老年代使用一种回收策略,取而代之的是一种整体的内存回收策略。
这种回收策略在我们当下cpu、内存、服务规模都越来越大的情况下提供了更好的表现,而这一代ZGC更是有了突破性的进步。
从原理上来理解,ZGC可以看做是G1之上更细粒度的内存管理策略。由于内存的不断分配回收会产生大量的内存碎片空间,因此需要整理策略防止内存空间碎片化。
在整理期间需要将对于内存引用的线程逻辑暂停,这个过程被称为Stop the world。只有当整理完成后,线程逻辑才可以继续运行。
JDK17有哪些特性?
JDK17是JavaSE平台版本17的开源参考实现,由JSR392在JCP(JavaCommunityProcess)指定。 根据发布的规划,这次发布的JDK17将是一个长期支持版(LTS版)。 LTS版每3年发布一个,上一次长期支持版是18年9月发布的JDK11。 JDK17具有以下提议的特性:-JEP415:特定于上下文的反序列化过滤器-JEP414:VectorAPI(第二个孵化器)-JEP412:外部函数和内存API(孵化器)-JEP411:弃用安全管-JEP389:macOS/AArch64端口-JEP388:Windows/AArch64端口
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。