大家好,我是大杨,今天给大家介绍一下Java9的新特性,并提供一些代码示例。Java9带来了许多新的增强功能,它们将极大地影响您的编程风格和习惯。最大的变化是Java的模块化。这是继Java8中Lambdas之后的又一次重大变化。在本文中,我将列出Java9版本中的一些更新。本文主要内容:Java模块化接口私有方法HTTP/2客户端JShell-REPL工具平台和JVM日志记录过程API更新Collection(集合)API更新Stream(流)API改进多版本Jar文件@Deprecated注解变更Java文档更新其他功能1.Java模块化JPMS(JavaPlatformModuleSystem)是Java9版本的核心亮点。它也被称为Jigshaw项目。模块是新的结构,就像我们已经有了包一样。使用新的模块化编程开发的应用程序可以看作是交互模块的集合,它们之间具有明确定义的边界和依赖关系。JPMS包括对编写模块化应用程序和模块化JDK源代码的支持。JDK9附带了大约92个模块(可能会在GA版本中发生变化)。Java9模块系统有一个“java.base”模块。它被称为基本模块。它是一个独立的模块,不依赖于任何其他模块。默认情况下,所有其他模块都依赖于“java.base”。在java模块化编程中:模块通常只是一个jar文件,根目录中有一个文件module-info.class。要使用模块,请将jar文件包含到模块路径而不是类路径。添加到类路径的模块jar文件是普通jar文件,module-info.class文件将被忽略。一个典型的module-info.java类是这样的:接受欢迎功能。从Java9开始,您可以在接口中使用私有方法。这些私有方法将增加接口内代码的可重用性。例如,如果两个默认方法需要共享代码,私有接口方法将允许它们这样做,但不会将该私有方法暴露给它的实现类。在接口中使用私有方法有四个规则:私有接口方法不能是抽象的。私有方法只能在接口内部使用。私有静态方法可以在其他静态和非静态接口方法中使用。私有静态方法不能使用私有非静态方法。示例:publicinterfaceCustomCalculator{defaultintaddEvenNumbers(int...nums){returnadd(n->n%2==0,nums);}默认intaddOddNumbers(int...nums){returnadd(n->n%2!=0,nums);}privateintadd(IntPredicatepredicate,int...nums){returnIntStream.of(nums).filter(predicate).sum();}}3。HTTP/2客户端HTTP/1.1客户端于1997年发布。从那时起发生了很多变化。因此Java9引入了新的API,它使用起来更干净、更清晰,并且还添加了对HTTP/2的支持。新API使用3个主要类HttpClient、HttpRequest和HttpResponse。要发出请求,很简单,就是获取客户端,构建请求并发送它,例如:HttpClienthttpClient=HttpClient.newHttpClient();HttpRequesthttpRequest=HttpRequest.newBuilder().uri(newURI("https://baidu.com/")).GET().build();HttpResponsehttpResponse=httpClient.send(httpRequest,HttpResponse.BodyHandler.asString());系统。out.println(httpResponse.body());上面的代码看起来更加清晰易读。httpClient.sendAsync()API还支持使用该方法的异步HTTP请求。它返回一个CompletableFuture,可用于确定请求是否已完成。也可以在HttpResponse请求完成后访问。如果需要,您甚至可以在请求完成之前取消它。示例:if(httpResponse.isDone()){System.out.println(httpResponse.get().statusCode());System.out.println(httpResponse.get().body());}else{httpResponse.cancel(true);}4.JShell–REPL工具JShell是JDK9版本[JEP222]中包含的一种新的命令行交互工具,用于评估用Java编写的声明、语句和表达式。JShell允许我们执行Java代码片段并立即获得结果,而无需创建解决方案项目。Jshell很像我们在linux操作系统中的命令窗口。不同之处在于JShell是特定于Java的。除了执行简单的代码片段外,它还有许多其他功能,例如:在单独的窗口中启动内置代码编辑器当在这些外部编辑器中发生保存操作时,在单独的窗口中启动您选择的代码编辑器从文件系统编写的类5.平台和JVM日志记录JDK9使用新的日志记录API改进了平台类(JDK类)和JVM组件的日志记录。它允许开发人员指定他们选择的日志记录框架(例如Log4J2)作为记录来自JDK类的消息的日志记录工具。关于此API,您应该了解以下几点:该API旨在供JDK中的类使用,而不是供应用程序类使用。对于应用程序代码,开发人员将继续像以前一样使用其他日志记录API。API不允许开发人员以编程方式配置记录器。API由以下几部分组成:服务接口,java.lang.System.LoggerFinder是一个抽象静态类java.lang.System.Logger提供日志记录API接口getLogger()是java.lang.System的一个重载方法,它返回一个logger实例。JDK9还添加了一个新的命令行选项-Xlog,它为开发人员提供了对从JVM所有类记录的所有消息的单一访问点。以下是使用-Xlog选项的语法:-Xlog[:][:[][:[][:]]]所有选项都是可选的。如果缺少前面的部分,-Xlog必须为该部分使用冒号。例如,-Xlog::stderr表示所有部分都默认,输出设置为stderr。6.进程API更新在Java5之前,生成新进程的唯一方法是使用Runtime.getRuntime().exec()方法。然后在Java5中,引入了ProcessBuilderAPI,它支持以更简洁的方式生成新进程。现在,Java9添加了一种新方法来获取有关当前进程和任何派生进程的信息。要获取任何进程的信息,现在您应该使用java.lang.ProcessHandle.Info接口。这个接口可以用来获取很多信息,例如:commandcommand用于启动进程的参数进程启动的那一刻花费的总时间和创建它的用户ProcessHandleprocessHandle=ProcessHandle.current();ProcessHandle.InfoprocessInfo=processHandle.info();System.out.println(processHandle.getPid());System.out.println(processInfo.arguments().isPresent());System.out.println(pprocessInfo.command().isPresent());System.out.println(processInfo.command().get().contains("java"));System.out.println(processInfo.startInstant().isPresent());要获取有关新生成的进程的信息,请使用process.toHandle()方法获取ProcessHandle实例。其他一切如上。字符串javaPrompt=ProcessUtils.getJavaCmd().getAbsolutePath();ProcessBuilderprocessBuilder=newProcessBuilder(javaPrompt,"-version");进程process=processBuilder.inheritIO().start();ProcessHandleprocessHandle=process.toHandle();使用ProcessHandle.allProcesses()获取系统中所有可用进程的ProcessHandle流。要获取所有子进程的列表(直接和n级深度),请使用children()和descendants()方法。Streamchildren=ProcessHandle.current().children();Streamdescendants=ProcessHandle.current().descendants();6.集合(Collection)API更新从Java9开始,可以使用新的工厂方法创建不可变集合,例如不可变列表、不可变集合和不可变映射。例如:导入java.util.List;公共类ImmutableCollections{publicstaticvoidmain(String[]args){ListnamesList=List.of("Lokesh","Amit","John");SetnamesSet=Set.of("Lokesh","Amit","John");MapnamesMap=Map.ofEntries(Map.entry("1","Lokesh"),Map.entry("2","Amit"),Map.entry("3","Brian"));}}7.Stream(流)API改进Java9引入了两种与Streams交互的新方法,即takeWhile/dropWhile方法。此外,它还添加了两个重载方法,ofNullable和iterate方法。新方法takeWhile。dropWhile允许开发人员基于谓词获取流的一部分在有序流上,takeWhile返回从流中获取的与给定谓词匹配的元素的“最长前缀”,从流的开头开始。dropWhile返回与takeWhile不匹配的剩余项。在无序流上,takeWhile返回与给定谓词匹配的流元素子集(但不是全部),从流的开头开始。dropWhile在删除与给定谓词匹配的元素子集后返回剩余的流元素。List字母表=List.of("a","b","c","d","e","f","g","h","i");Listsubset1=alphabets.stream().takeWhile(s->!s.equals("d")).collect(Collectors.toList());//打印出来:[a,b,c]System.out.println(subset1);Listalphabets=List.of("a","b","c","d","e","f","g","h","i");Listsubset2=alphabets.stream().dropWhile(s->!s.equals("d")).collect(Collectors.toList());//打印输出:[d,e,f,g,h,i]System.out.println(subset2);还有,在Java8之前,流中不能有空值。它会导致NullPointerException。从Java9开始,Stream.ofNullable()方法允许您创建一个单元素流,它包装一个非空值,否则为空流。从技术上讲,Stream.ofNullable()非常类似于流API上下文中的空条件检查。8.多版本Jar文件此增强功能与应用程序类如何打包成jar文件有关。以前,开发人员必须将所有类打包到一个jar文件中,并将其放在另一个要使用它的应用程序的类路径中。使用多版本功能,现在单个jar可以包含一个类的不同版本——与不同的JDK版本兼容。有关类的不同版本以及加载的类应该选择哪个JDK版本的信息存储在MANIFEST.MF文件中。在这种情况下,文件MANIFEST.MF在其主要部分包含条目Multi-Release:true。此外,META-INF包含一个发布子目录,其中包含以9开??头的整数命名子目录(对于Java9)——存储特定于版本的类和资源文件。例如,JAR内容根目录A.classB.classC.classD.classMETA-INFMANIFEST.MFversions9A.classB.class假设更新JDK10A.class以利用一些新的Java10功能,那么这个Jar文件可以这样更新:JARcontentrootA.classB.classC.classD.classMETA-INFMANIFEST.MFversions9A.classB.class10A.class看起来很有前途解决大型应用程序中经常会出现依赖地狱,不同版本的jar相互不兼容。此功能可以极大地帮助解决这些情况。9、@Deprecated注解的变化从Java9开始,@Deprecated注解会有两个属性,分别是forRemoval和since.forRemoval——表示被注解的元素在以后的版本中是否会被移除。since-它返回注释元素的弃用版本。强烈建议使用@deprecatedjavadoc标记来解释文档中不推荐使用程序元素的原因。如果适用,文档还应建议并链接到推荐的替代API。替换API通常具有细微不同的语义,因此也应讨论此类问题。10.Java文档更新Java9增强了javadoc生成HTML5标记的工具。它目前以HTML4.01生成页面。为了生成HTML5Javadoc,参数-html5需要放在命令行参数中。要在命令行上生成文档,您可以运行:javadoc[options][packagename][sourcefiles][@files]使用HTML5的好处是HTML5结构更简单。它还实现了WAI-ARIA可访问性标准。这是为了让有身体或视觉障碍的人使用屏幕阅读器等工具更容易访问javadocs页面。JEP225提供了在javadoc中搜索程序元素和标签的单词和短语的能力。以下将被索引和搜索:模块的声明名称包类型和成员方法参数类型的简单名称这是在客户端用一个新的search.jsJavascript文件实现的,以及生成javadoc时产生的索引.生成的HTML5API页面上有一个搜索框。请注意,搜索选项是默认添加的,但可以使用参数关闭:-noindex。11.其他特性Java9中还有其他特性,我在此列出以供快速参考。我们将在即将发布的帖子中讨论所有这些功能。ReactiveStreamsAPIGC(垃圾收集器)改进过滤传入的序列化数据弃用的AppletAPI指示字符串连接增强的方法处理压缩字符串Nashorn解析器API