安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

Java每半年更新一次新特性,再不掌握就要落伍了Java9的

4月16日 发如雪投稿
  从2017年开始,Java版本更新策略从原来的每两年一个新版本,改为每六个月一个新版本,以快速验证新特性,推动Java的发展。从《JVMEcosystemReport2021》中可以看出,目前开发环境中有近半的环境使用Java8,有近半的人转移到了Java11,随着Java17的发布,相信比例会有所变化。
  因此,准备出一个系列,配合示例讲解,阐述各个版本的新特性。概述
  相较于Java8,Java9没有新增语法糖,但是其增加的特性也都是非常实用的,比如Jigsaw模块化、JShell、发布订阅框架、GC等。本文将快速、高层次的介绍一些新特性,完整的特性可以参加openjdk。java。netprojectsjd
  这里需要说明一下,由于Java9并不是长期支持版,当前也是从现在看过去,所以笔者偷个懒,文章的示例代码都是在Java11下写的,可能会与Java9中的定义有些出入,不过,这也没啥,毕竟我们真正使用的时候还是优先考虑长期支持版。Jigsaw模块化
  模块化是一个比较大的更新,这让以前AllinOne的Java包拆分成几个模块。这种模块化系统提供了类似OSGi框架系统的功能,比如多个模块可以独立开发,按需引用、按需集成,最终组装成一个完整功能。
  模块具有依赖的概念,可以导出功能API,可以隐藏实现细节。
  还有一个好处是可以实现JVM的按需使用,能够减小Java运行包的体积,让JVM在内存更小的设备上运行。JVM当时的初衷就是做硬件,也算是不忘初心了。
  另外,JVM中com。sun。的之类的内部API,做了更强的封闭,不在允许调用,提升了内核安全。
  在使用的时候,我们需要在java代码的顶层目录中定义一个moduleinfo。java文件,用于描述模块信息:modulecn。howardliu。java9。modules。car{requirescn。howardliu。java9。modules。exportscn。howardliu。java9。modules。car。}复制代码
  上面描述的信息是:模块cn。howardliu。java9。modules。car需要依赖模块cn。howardliu。java9。modules。engines,并导出模块cn。howardliu。java9。modules。car。handling。
  更多的信息可以查看OpenJDK的指引openjdk。java。netprojectsjiJigsaw模块的使用,内容会贴到评论区。全新的HTTP客户端
  这是一个千呼万唤始出来的功能,终于有官方API可以替换老旧难用的HttpURLConnection。只不过,在Java9中,新版HTTP客户端是放在孵化模块中(具体信息可以查看openjdk。java。netjeps110)。
  老版HTTP客户端存在很多问题,大家开发的时候基本上都是使用第三方HTTP库,比如ApacheHttpClient、Netty、Jetty等。
  新版HTTP客户端的目标很多,毕竟这么多珠玉在前,如果还是做成一坨,指定是要被笑死的。所以新版HTTP客户端列出了16个目标,包括简单易用、打印关键信息、WebSocket、HTTP2、HTTPSTLS、良好的性能、非阻塞API等等。
  我们先简单的瞅瞅:finalStringurlhttps:postmanecho。finalHttpRequestrequestHttpRequest。newBuilder()。uri(newURI(url))。GET()。build();finalHttpResponseStringresponseHttpClient。newHttpClient()。send(request,HttpResponse。BodyHandlers。ofString());finalHttpHeadersheadersresponse。headers();headers。map()。forEach((k,v)System。out。println(k:v));System。out。println(response。statusCode());System。out。println(response。body());复制代码
  新版HTTP客户端可以在Java11中正常使用了,上面的代码也是在Java11中写的,API是在java。net。http包中。改进的进程API
  在Java9中提供的进程API,可以控制和管理操作系统进程。也就是说,可以在代码中管理当前进程,甚至可以销毁当前进程。进程信息
  这个功能是由java。lang。ProcessHandle提供的,我们来瞅瞅怎么用:finalProcessHandleselfProcessHandle。current();finallongpidself。pid();System。out。println(PID:pid);finalProcessHandle。InfoprocInfoself。info();procInfo。arguments()。ifPresent(x{for(Strings:x){System。out。println(s);}});procInfo。commandLine()。ifPresent(System。out::println);procInfo。startInstant()。ifPresent(System。out::println);procInfo。totalCpuDuration()。ifPresent(System。out::println);复制代码
  java。lang。ProcessHandle。Info中提供了丰富的进程信息销毁进程
  我们还可以使用java。lang。ProcessHandledestroy方法销毁进程,我们演示一下销毁子进程:ProcessHandle。current()。children()。forEach(procHandle{System。out。println(procHandle。pid());System。out。println(procHandle。destroy());});复制代码
  从Java8之后,我们会发现Java提供的API使用了Optional、Stream等功能,Eatingyourowndogfood也是比较值得学习的。其他小改动
  Java9中还对做了对已有功能做了点改动,我们来瞅瞅都有哪些。改进trywithresources
  从Java7开始,我们可以使用trywithresources语法自动关闭资源,所有实现了java。lang。AutoCloseable接口,可以作为资源。但是这里会有一个限制,就是每个资源需要声明一个新变量。
  也就是这样:publicstaticvoidtryWithResources()throwsIOException{try(FileInputStreamin2newFileInputStream(。)){dosomething}}复制代码
  对于这种直接使用的还算方便,但如果是需要经过一些列方法定义的呢?就得写成下面这个样子:finalReaderinputStringnewStringReader(www。howardliu。cn看山);finalBufferedReaderbrnewBufferedReader(inputString);其他一些逻辑try(BufferedReaderbr1br){System。out。println(br1。lines());}复制代码
  在Java9中,如果资源是final定义的或者等同于final变量,就不用声明新的变量名,可以直接在trywithresources中使用:finalReaderinputStringnewStringReader(www。howardliu。cn看山);finalBufferedReaderbrnewBufferedReader(inputString);其他一些逻辑try(br){System。out。println(br。lines());}复制代码改进钻石操作符(DiamondOperator)
  钻石操作符(也就是)是Java7引入的,可以简化泛型的书写,比如:MapString,ListStringstrsMapnewTreeMapString,ListString();复制代码
  右侧的TreeMap类型可以根据左侧的泛型定义推断出来,借助钻石操作符可以简化为:MapString,ListStringstrsMapnewTreeMap();复制代码
  看山会简洁很多,的写法就是钻石操作符(DiamondOperator)。
  但是这种写法不适用于匿名内部类。比如有个抽象类:abstractstaticclassConsumerT{privateTpublicConsumer(Tcontent){this。}abstractvoidaccept();publicTgetContent(){}}复制代码
  在Java9之前,想要实现匿名内部类,就需要写成:finalConsumerIntegerintConsumernewConsumerInteger(1){Overridevoidaccept(){System。out。println(getContent());}};intConsumer。accept();finalC?extendsNumbernumConsumernewConsumerNumber(BigDecimal。TEN){Overridevoidaccept(){System。out。println(getContent());}};numConsumer。accept();finalC?objConsumernewConsumerObject(看山){Overridevoidaccept(){System。out。println(getContent());}};objConsumer。accept();复制代码
  在Java9之后就可以使用钻石操作符了:finalConsumerIntegerintConsumernewConsumer(1){Overridevoidaccept(){System。out。println(getContent());}};intConsumer。accept();finalC?extendsNumbernumConsumernewConsumer(BigDecimal。TEN){Overridevoidaccept(){System。out。println(getContent());}};numConsumer。accept();finalC?objConsumernewConsumer(看山){Overridevoidaccept(){System。out。println(getContent());}};objConsumer。accept();复制代码私有接口方法
  如果说钻石操作符是代码的简洁可读,那接口的私有方法就是比较实用的一个扩展了。
  在Java8之前,接口只能有常量和抽象方法,想要有具体的实现,就只能借助抽象类,但是Java是单继承,有很多场景会受到限制。
  在Java8之后,接口中可以定义默认方法和静态方法,提供了很多扩展。但这些方法都是public方法,是完全对外暴露的。如果有一个方法,只想在接口中使用,不想将其暴露出来,就没有办法了。这个问题在Java9中得到了解决。我们可以使用private修饰,限制其作用域。
  比如:publicinterfaceMetric{常量StringNAMEMETRIC;抽象方法voidinfo();私有方法privatevoidappend(Stringtag,Stringinfo){buildMetricInfo();System。out。println(NAME〔tag〕:info);clearMetricInfo();}默认方法defaultvoidappendGlobal(Stringmessage){append(GLOBAL,message);}默认方法defaultvoidappendDetail(Stringmessage){append(DETAIL,message);}私有静态方法privatestaticvoidbuildMetricInfo(){System。out。println(buildbasemetric);}私有静态方法privatestaticvoidclearMetricInfo(){System。out。println(clearbasemetric);}}复制代码JShell
  JShell就是Java语言提供的REPL(ReadEvalPrintLoop,交互式的编程环境)环境。在Python、Node之类的语言,很早就带有这种环境,可以很方便的执行Java语句,快速验证一些语法、功能等。jshell欢迎使用JShell版本13。0。9要大致了解该版本,请键入:helpintro复制代码
  我们可以直接使用help查看命令jshellhelp键入Java语言表达式,语句或声明。或者键入以下命令之一:list〔名称或idallstart〕列出您键入的源edit名称或id。很多的内容,鉴于篇幅,先隐藏复制代码
  我们看下一些简单的操作:jshellThisisatest。。substring(5,10);2isajshell3134复制代码
  也可以创建方法:jshellintmulitiTen(inti){returni10;}已创建方法mulitiTen(int)jshellmulitiTen(3)630复制代码
  想要退出JShell直接输入:jshellexit再见复制代码JCMD新增子命令
  jcmd是用于向本地jvm进程发送诊断命令,这个命令是从JDK7提供的命令行工具,常用于快速定位线上环境故障。
  在JDK9之后,提供了一些新的子命令,查看JVM中加载的所有类及其继承结构的列表。比如:jcmd22922VM。classhierarchyisjava。net。Socket22922:java。lang。Objectnulljava。net。Socketnullimplementsjava。io。Closeablenull(declaredintf)implementsjava。lang。AutoCloseablenull(inheritedintf)sun。nio。ch。SocketAdaptornullimplementsjava。lang。AutoCloseablenull(inheritedintf)implementsjava。io。Closeablenull(inheritedintf)复制代码
  第一个参数是进程ID,都是针对这个进程执行诊断。我们还可以使用setvmflag参数在线修改JVM参数,这种操作无需重启JVM进程。
  有时候还需要查看当前进程的虚拟机参数选项和当前值:jcmd22922VM。flagsall。多分辨率图像API
  在Java9中定义了多分辨率图像API,我们可以很容易的操作和展示不同分辨率的图像了。java。awt。image。MultiResolutionImage将一组具有不同分辨率的图像封装到单个对象中。java。awt。Graphics类根据当前显示DPI度量和任何应用的转换从多分辨率图像中获取变量。
  以下是多分辨率图像的主要操作方法:ImagegetResolutionVariant(doubledestImageWidth,doubledestImageHeight):获取特定分辨率的图像变体表示一张已知分辨率单位为DPI的特定尺寸大小的逻辑图像,并且这张图像是最佳的变体。ListgetResolutionVariants():返回可读的分辨率的图像变体列表。
  我们来看下应用:finalListImageimagesList。of(ImageIO。read(newURL(https:static。howardliu。cnaboutkanshanshuo2。png)),ImageIO。read(newURL(https:static。howardliu。cnabouthellokanshan。png)),ImageIO。read(newURL(https:static。howardliu。cnaboutevil20coder。jpg)));读取所有图片finalMultiResolutionImagemultiResolutionImagenewBaseMultiResolutionImage(images。toArray(newImage〔0〕));获取图片的所有分辨率finalListImagevariantsmultiResolutionImage。getResolutionVariants();System。out。println(Totalnumberofimages:variants。size());for(Imageimg:variants){System。out。println(img);}根据不同尺寸获取对应的图像分辨率Imagevariant1multiResolutionImage。getResolutionVariant(100,100);System。out。printf(Imagefordestination〔d,d〕:〔d,d〕,100,100,variant1。getWidth(null),variant1。getHeight(null));Imagevariant2multiResolutionImage。getResolutionVariant(200,200);System。out。printf(Imagefordestination〔d,d〕:〔d,d〕,200,200,variant2。getWidth(null),variant2。getHeight(null));Imagevariant3multiResolutionImage。getResolutionVariant(300,300);System。out。printf(Imagefordestination〔d,d〕:〔d,d〕,300,300,variant3。getWidth(null),variant3。getHeight(null));Imagevariant4multiResolutionImage。getResolutionVariant(400,400);System。out。printf(Imagefordestination〔d,d〕:〔d,d〕,400,400,variant4。getWidth(null),variant4。getHeight(null));Imagevariant5multiResolutionImage。getResolutionVariant(500,500);System。out。printf(Imagefordestination〔d,d〕:〔d,d〕,500,500,variant5。getWidth(null),variant5。getHeight(null));复制代码变量句柄(VariableHandles)
  变量句柄(VariableHandles)的API主要是用来替代java。util。concurrent。atomic包和sun。misc。Unsafe类的部分功能,并且提供了一系列标准的内存屏障操作,用来更加细粒度的控制内存排序。一个变量句柄是一个变量(任何字段、数组元素、静态表里等)的类型引用,支持在不同访问模型下对这些类型变量的访问,包括简单的readwrite访问,volatile类型的readwrite访问,和CAS(compareandswap)等。
  这部分内容涉及反射、内联、并发等内容,后续会单独介绍,文章最终会发布在从小工到专家的Java进阶之旅中,敬请关注。发布订阅框架
  在Java9中增加的java。util。concurrent。Flow支持响应式API的发布订阅框架,他们提供在JVM上运行的许多异步系统之间的互操作性。我们可以借助SubmissionPublisher定制组件。
  关于响应式API的内容可以先查看www。reactivestreams。org的内容,后续单独介绍,从小工到专家的Java进阶之旅中,敬请关注。怎么感觉给自己刨了这么多坑,得抓紧时间填坑了。统一JVM日志记录
  在这个版本中,为JVM的所有组件引入了一个通用的日志系统。它提供了日志记录的基础。这个功能是通过Xlog启动参数指定,并且定义很多标签用来定义不同类型日志,比如:gc(垃圾收集)、compiler(编译)、threads(线程)等等。比如,我们定义debug等级的gc日志,日志存储在gc。log文件中:javaXlog:gcdebug:filegc。log:none复制代码
  因为参数比较多,我们可以通过javaXlog:help查看具体定义参数。而且日志配置可以通过jcmd命令动态修改,比如,我们将日志输出文件修改为gcother。log:jcmd{PID}VM。logoutputgcother。logwhatgc复制代码新的API不可变集合
  在Java9中增加的java。util。List。of()、java。util。Set。of()、java。util。Map。of()系列方法,可以一行代码创建不可变集合。在Java9之前,我们想要初始化一个有指定值的集合,需要执行一堆add或put方法,或者依赖guava框架。
  而且,这些集合对象是可变的,假设我们将值传入某个方法,我们就没有办法控制这些集合的值不会被修改。在Java9之后,我们可以借助ImmutableCollections中的定义实现初始化一个不可变的、有初始值的集合了。如果对这些对象进行修改(新增元素、删除元素),就会抛出UnsupportedOperationException异常。
  这里不得不提的是,Java开发者们也是考虑了性能,针对不同数量的集合,提供了不同的实现类:List12、Set12、Map1专门用于少量(List和Set是2个,对于Map是1对)元素数量的场景ListN、SetN、MapN用于数据量多(List和Set是超过2个,对于Map是多余1对)的场景改进的Optional类
  Java9中为Optional添加了三个实用方法:stream、ifPresentOrElse、or。
  stream是将Optional转为一个Stream,如果该Optional中包含值,那么就返回包含这个值的Stream,否则返回Stream。empty()。比如,我们有一个集合,需要过滤非空数据,在Java9之前,写法如下:finalListOptionalStringlistArrays。asList(Optional。empty(),Optional。of(看山),Optional。empty(),Optional。of(看山的小屋));finalListStringfilteredListlist。stream()。flatMap(oo。isPresent()?Stream。of(o。get()):Stream。empty())。collect(Collectors。toList());复制代码
  在Java9之后,我们可以借助stream方法:finalListStringfilteredListJava9list。stream()。flatMap(Optional::stream)。collect(Collectors。toList());复制代码
  ifPresentOrElse:如果一个Optional包含值,则对其包含的值调用函数action,即action。accept(value),这与ifPresent方法一致;如果Optional不包含值,那会调用emptyAction,即emptyAction。run()。效果如下:OptionalIntegeroptionalOptional。of(1);optional。ifPresentOrElse(xSystem。out。println(Value:x),()System。out。println(NotPresent。));optionalOptional。empty();optional。ifPresentOrElse(xSystem。out。println(Value:x),()System。out。println(NotPresent。));输出结果为:作者:看山佚名复制代码
  or:如果值存在,返回Optional指定的值,否则返回一个预设的值。效果如下:OptionalStringoptional1Optional。of(看山);SupplierOptionalStringsupplierString()Optional。of(佚名);optional1optional1。or(supplierString);optional1。ifPresent(xSystem。out。println(作者:x));optional1Optional。empty();optional1optional1。or(supplierString);optional1。ifPresent(xSystem。out。println(作者:x));输出结果为:作者:看山作者:佚名复制代码文末总结
  本文介绍了Java9新增的特性,完整的特性清单可以从openjdk。java。netprojectsjdJava8到Java17的新特性系列完成后补充,青山不改,绿水长流,我们下次见。
  原文链接:https:juejin。cnpost7061389685699903525
投诉 评论 转载

中国酒业协会宋书玉2019将是中国白酒产业新的元年3月24日27日,第十三届中国国际酒业博览会在泸州隆重开幕。今日头条作为本届酒博会首席资讯合作伙伴,在泸州对话了中国酒业协会副理事长兼秘书长、中国酿酒大师宋书玉。中国酒业……手机现状大牌苹果是真爱,国产销量差,三星无人问起?在国内手机有很多品牌,有大家平常喜欢的苹果、OPPO、小米、荣耀、华为等,但是大牌苹果手机才是真爱,国产机买的人少,为何三星无人问起?下面小编为大家详细介绍为何会发生这样的情况……数字人民币加快试点步伐流通服务层蕴藏隐形冠军随着试点城市的不断增加以及受理场景的逐步铺开,数字人民币正在引发越来越多的讨论。众所周知,数字人民币和支付机构的关系一直是业内的关切点,坊间也流传着数字人民币就是要取代第三方支……芯片断供到现在,美国发现加大力度不行维持现状也不行。想合作了很多人不明白为什么美国一边开放允许中芯国际进口14nm光刻机设备,一边又加紧断供华为。今天我就说说自己的看法,如果不全面欢迎你们补充。其实从美国波士顿咨询公司的最新报告就……一英寸大底,索尼XperiaPROI这款超越微单的旗舰手机终对于索尼手机的印象应该还停留在索尼XperiaXA2Ultra,那也是笔者接触的第一款索尼专业影像级的一款手机,不管是拍摄体验还是手机外观,都可以说可圈可点,在千篇一律的手机市……WEY摩卡可能是国内最智能的燃油车2014年,罗永浩在锤砸西门子冰箱之后,终于在手机市场重现雄风,推出了自己的参赛作品SmartisanT1智能手机。彼时,受限于新广告法的限制,后来手撕王自如的罗永浩灵机一动,……快报小米12配置曝iPhone13电池增大vivo弹出式摄像荣耀Magic3五摄镜头曝光近日,荣耀终端有限公司CEO赵明手持了一款从未见过的新机,不出意外该机就是荣耀Magic3系列新机。虽然这款手机带着保护壳,但依然能够看……JEETONE和漫步者lollipods蓝牙耳机哪个好?上手作为数码发烧友,平时最爱的就是在各种耳机论坛逛逛,对耳机、蓝牙耳机都了如指掌。看到不少网友在讨论JEETONE和漫步者lollipods蓝牙耳机哪个好,我入手这两款蓝牙耳机已经……今日头条申请认证,与不认证的区别是什么?你好,我是全职自媒体人,很荣幸回答你的问题。以下观点和建议,供参考:头条有几个认证,不同的认证,作用不同。不知道你说的哪个,一一给你说下吧。几个认证分别是:实名认证,兴趣……手机解锁又有新方式?OPPO静脉解锁专利获授权随着科学技术的不断进步,尤其是生物识别技术的发展,让人们可以通过该技术实现各种更加安全,高效的场景体验。就明显的例子就是手机解锁,指纹解锁、人脸识别解锁都已经被广泛应用,大家在……英伟达收购ARM再受阻!400亿美元交易要黄?中新经纬12月3日电美国芯片巨头英伟达(NVIDIA)400亿美元收购英国芯片设计公司ARM的交易再度受阻。据日经中文网报道,当地时间12月2日,美国联邦贸易委员会(FT……Java每半年更新一次新特性,再不掌握就要落伍了Java9的从2017年开始,Java版本更新策略从原来的每两年一个新版本,改为每六个月一个新版本,以快速验证新特性,推动Java的发展。从《JVMEcosystemReport2021》……
从今天起,将联想笔记本logo贴住,直至它从我生活中消失有人说,助听器会越戴越聋,这是不是真的?有何依据?世界上最玩命的猎蜂人,攀爬悬崖去采蜜苹果帝国VS阿里帝国百度推出小度智能巨屏电视及小度智能词典笔如何评价华为海思麒麟980?华为matebook14怎么样?从加拿大鹅到苹果双标政策让国际巨头正遭受信任危机在中国一千人中多少人用苹果手机?腾龙新变焦镜头规格曝光警惕阿里,腾讯,美团等外资企业营造虚拟经济带来的虚假繁荣对抗黑客零日攻击苹果发布紧急安全更新

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利