javaee概览_Java 9概览

javaee概览

对于许多Java 9来说,似乎是一个维护版本,它推动了不能在Java 8中实现的项目Jigsaw。但是,随着JDK中的新模块系统以及与之相关的许多内部更改,Java 9也带来了开发人员工具箱中一些很棒的新内容。 以下是重点内容:

  • JShell – Java现在具有内置的外壳;
  • 新的流程API –提供许多功能来处理以前版本中默认缺少的流程;
  • 将G1用作默认的垃圾收集器–在Java 8中,这是并行GC;
  • 全新的HTTP / 2客户端-由jdk.incubator.httpclient.HttpClient类和jdk.incubator.httpclient包的类提供;
  • 新的堆栈遍历API –提供了用于分析和使用Java堆栈跟踪的标准API;
  • 新的React式编程API –在JDK java.util.concurrent.Flow类中提供了一种标准机制;
  • 语言增强功能–这些是一些较小的语言改进,最重要的是在接口中具有私有方法的能力(例如,供Java 8中默认使用的方法使用)。 在Java 10中迁移了将var关键字引入该语言的较早建议(尽管最初计划是9)。 Coin项目将带来进一步的改进(包括一系列小的语言更改);
  • 杂项–改进的Javadoc,集合工厂方法(如Set.of(…),Map.of(…),List.of(…)),流API改进,私有接口方法,多发行版JAR和许多其他方法(包括并发性和安全性增强)(本文并不涉及)(好奇的读者可以在此处查看与Java 9相关的JEP: http : //openjdk.java.net/projects/jdk9/ )。

在JDK 9中没有实现的另一件事是打包了JMH工具,并提供了供应用程序使用的默认JMH微基准-那里的工作仍在进行中……

打破整体

让我们考虑一下,我们有一个Java 9之前的应用程序,可以将文本导出为不同的格式-文本,pdf或word。 应用程序结构如下:

exporter.IExporter接口为不同的出口商提供了公共接口:

public interface IExporter {public void export(String text, ByteArrayOutputStream baos);	
}

以下是三个具体的导出器实现:

public class PdfExporter implements IExporter {public void export(String text, ByteArrayOutputStream baos) {Document document = null;try {document = new Document();PdfWriter.getInstance(document, baos);document.open();document.add(new Paragraph(text));document.close();} catch (DocumentException e) {if (document != null) {document.close();}}}
}
public class WordExporter implements IExporter {public void export(String text, ByteArrayOutputStream baos) {XWPFDocument document = null;try {document = new XWPFDocument();XWPFParagraph paragraph = document.createParagraph();XWPFRun run = paragraph.createRun();run.setText(text);document.write(baos);} catch (IOException e) {try {if (document != null) {document.close();}} catch (IOException e1) {}// some logging or proper error handling ...}}
}
public class TextExporter implements IExporter {public void export(String text, ByteArrayOutputStream baos) {try {baos.write(text.getBytes());} catch (IOException e) {// some logging or proper error handling ...}}
}

exporter.Main类是应用程序的入口点,如果可能具有以下实现,则仅使用PdfExporter类:

public static void main(String[] args) throws IOException {PdfExporter exporter = new PdfExporter();ByteArrayOutputStream baos = new ByteArrayOutputStream();exporter.export("sample text", baos);FileOutputStream fos = new FileOutputStream("example.pdf");fos.write(baos.toByteArray());fos.close();
}

对于PDF和Word导出器,我们需要以下依赖项(我们使用Maven来构建应用程序):

<dependencies><dependency><groupid>org.apache.poi</groupid><artifactid>poi</artifactid><version>3.16</version></dependency><dependency><groupid>org.apache.poi</groupid><artifactid>poi-ooxml</artifactid><version>3.16</version></dependency><dependency><groupid>com.lowagie</groupid><artifactid>itext</artifactid><version>2.1.7</version></dependency>		
</dependencies>

因此,第一件事就是为您的应用程序定义模块以及您将要使用的JDK模块。 您的初始应用程序在类路径上具有所有JDK类,但是您可以将Java 9中的类仅限制为所需的JDK模块。 对于我们的简单应用程序,我们仅使用JDK中的java.io类,它们是每个Java应用程序都需要的java.base模块的一部分。 简单的应用程序不需要其他JDK模块,因此我们可以为应用程序使用JRE的极简版本。

对于实际应用,我们可以轻松地得出四个逻辑模块:

  • 出口商 –此模块为所有出口商提供通用API(exporter.IExporter类);
  • exporter.word –此模块提供Word导出程序;
  • exporter.pdf –此模块提供PDF导出器;
  • exporter.text –此模块提供文本导出器;
  • exporter.demo –此模块包含Main类,并提供我们应用程序的入口点。

接下来是为我们定义的每个模块添加模块元数据。 为此,我们为每个模块定义一个module-info.java文件,如下所示:

每个模块的模块元数据具有以下内容(请注意三个具体的导出器如何依赖于API模块,并且由于隐式需要而我们不需要java.base模块):

module exporter {exports exporter;
}
module exporter.pdf {requires exporter;requires itext;exports exporter.pdf;
}
module exporter.text {requires exporter;exports exporter.text;
}
module exporter.word {requires exporter;
}
module exporter.demo {requires exporter;requires poi.ooxml;requires poi.ooxml.schemas;exports exporter.word;
}

我们仍然需要以某种方式引用模块中的第三方库(IText和Apache POI)。 如果这些库是模块化版本,我们可以简单地下载它们并在相应的应用程序模块中需要它们。 但是,我们无法做出此假设,因此我们需要一种“按原样”将其称为依赖项的方法。 为了进行迁移,Java平台提供了一种将第三方库用作Java模块的机制。 如果这些位于我们应用程序的类路径中,它们将包含在全局“未命名”模块中,并且库中的所有公共类对我们的应用程序模块都是可见的。 另一方面,为模块化应用程序引入了新的模块路径,该路径指定了所有应用程序模块,还可以使用JAR文件的名称(不带.jar扩展名)从模块路径中引用第三方库-这些即所谓的自动模块。 我们希望第二种选择是更“模块化”的迁移方法。 现在,最后一件事是构建并运行我们的模块化应用程序。 实际上,我们对模块结构有不同的策略:例如同一项目中的多个模块(我们拥有一个模块),每个项目一个模块甚至是嵌套的模块结构。 同样,我们可以将module-info.java文件放置在模块中所需的任何位置,只要是在javac编译过程中指定的位置即可(因此位于模块目录的根目录中)。

在撰写本文时,Maven仍不支持模块化应用程序的构建,并且Java IDE(例如Eclipse,IntelliJ和NetBeans)对Jigsaw模块具有部分和实验性的支持。 因此,我们将演示如何从命令行构建模块化的应用程序。 为此,我们将首先在原始项目根目录中创建modules目录。 并按以下方式构建这五个模块中的每一个(请注意,Java 9还为javac提供了–module-source-path参数,以便可以立即编译模块,但我们将不会用于演示如何构建模块分别)–我们需要位于项目的根目录中,并在PATH上拥有最新的JDK 9 bin目录:

mkdir modules\exporter modules\exporter.pdf modules\exporter.word modules\exporter.text modules\exporter.demo
javac -d modules\exporter src\exporter\module-info.java src\exporter\IExporter.java
javac --module-path modules -d modules\exporter.text src\exporter\text\module-info.java src\exporter\text\TextExporter.java
javac --module-path modules;C:\Users\Martin\.m2\repository\com\lowagie\itext\2.1.7 -d modules\exporter.pdf src\exporter\pdf\module-info.java src\exporter\pdf\PdfExporter.java
javac -cp C:\Users\Martin\.m2\repository\org\apache\poi\poi\3.16\poi-3.16.jar --module-path modules;C:\Users\Martin\.m2\repository\org\apache\poi\poi-ooxml\3.16;C:\Users\Martin\.m2\repository\org\apache\poi\poi-ooxml-schemas\3.16 -d modules\exporter.word src\exporter\word\module-info.java src\exporter\word\WordExporter.java
javac --module-path modules -d modules\exporter.demo src\exporter\demo\module-info.java src\exporter\demo\Main.java

这里有两个要点。 首先,请确保从第三方依赖项的Maven目录中排除了源jar(如果有的话),因为这可能会使编译器误以为您在同一目录中有重复的模块jar(例如poi-3.16和poi-3.16-sources)。罐)。 其次,对于自动模块,您可能具有从不同库中导出的相同包(也称为拆分包 ),这在Java 9中是不允许的。ApachePOI就是这种情况: exporter.word模块需要poipoi-ooxml库导出org.apache.poi软件包,如果这两个软件包均作为自动模块包含在内,则会导致编译错误。 为了在我们的案例中解决此问题,我们在类路径上包括poi库,该库构成所谓的全局未命名模块,该模块在自动模块中可见。 现在,为了运行演示应用程序,您需要运行以下命令,将上面用于编译的模块路径/类路径组合在一起,并指向Main类作为应用程序的主要入口点:

javac --module-path modules -d modules\exporter.demo src\exporter\demo\module-info.java src\exporter\demo\Main.java

因此,您应该在当前目录中生成example.pdf文件。

玩弄Java Shell

JSHell REPL位于JDK9的bin目录中,您可以通过导航到该目录并键入jshell来简单地运行它。 您可以(重新)定义和检查变量,导入,方法和类型。 您还可以保存当前进度并将其重新加载到JSHell中。 还有对导入,类型和方法的出色自动完成支持。 为了说明JSHell的基础知识,请考虑在JShell中尝试以下命令集:

2 + 3
public int sum(int a, int b) { return a + b; }
import java.util.logging
import java.util.logging.*
Logger x = null;
class z {}
/help
/imports
/vars
/methods
/env
/types
/list
/list -all
/save script.jsh
/open script.jsh
/exit

控制外部流程

在Java 9之前,您可以使用两种方法来创建新进程–可以使用Runtime.getRuntime()。exec()方法或java.lang.ProcessBuilder类,如下所示:

Process p = Runtime.getRuntime().exec("cmd /c notepad");
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", “notepad");
Process p = pb.start();</pre>

但是,就管理已创建的进程或检查主机操作系统中的其他外部进程而言,这是相当有限的。 因此,JDK 9一方面向java.lang.Process类引入了许多新方法,另一方面为java.lang.ProcessHandle提供了新的实用程序,该实用程序允许以类似流的方式操纵外部流程。 以下是新流程API的一些自描述示例:

LOGGER.info("PID: " + process.pid());LOGGER.info("Number of children: " + process.children().count());LOGGER.info("Number of descendants: " + process.descendants().count());ProcessHandle.Info info = process.info();LOGGER.info("Process command: " + info.command());LOGGER.info("Info: " + info.toString());//		ProcessHandle handle = process.toHandle();CompletableFuture<process> exitedFuture = process.onExit();exitedFuture.whenComplete((p, e) -> { LOGGER.info("Process exited ... ");});exitedFuture.get();</process></pre>
<pre class="brush: java;">ProcessHandle[] processes = ProcessHandle.allProcesses().filter((pHandle) -> { return pHandle.info().toString().contains(name); }).toArray(ProcessHandle[] :: new);for(ProcessHandle process : processes) {LOGGER.info("Process details: " + process.info().toString());}return processes;

使用G1提升性能

G1垃圾收集器不是新增功能,而是在JDK 7中引入的。G1的特定之处在于,它按堆中的每个区域工作,而不是按代工作,这是清理垃圾的更细粒度的方法。 它的目的是在尊重一系列约束的同时,清理尽可能多的垃圾。 它是一种低暂停时间的收集器,可以在低暂停时间的情况下权衡高吞吐量。 在JDK 9中,它成为默认的垃圾回收器,取代了并行GC(即吞吐量更高的GC)。 做出此更改的假设是,由较低的GC暂停时间导致的用户体验改善要比收集器的高吞吐量更好(并行GC就是这种情况)。 这个假设是否成立还需要应用程序来决定–如果有人不愿意冒险使用G1,仍然可以使用-XX:-UseParallelGC为JVM指定并行GC。

为HTTP 2.0做好准备

jdk.incubator.http.HttpClient类提供了一个新的HTTP 2.0客户端,该客户端仍处于孵化阶段(这意味着可能会进行更多更改)。

走栈轨迹

java.lang.StackWalker类提供了新的堆栈跟踪检查API。 它可以用于使用类似流的操作以细粒度方式过滤和处理堆栈跟踪信息。

包含React式编程

想要提供适合于React式编程范例的发布-订阅机制的应用程序必须提供java.util.concurrent.Flow类的实现。 由JDK提供的一种实现Flow.Publisher接口的标准发布者,由java.util.concurrent.SubmissionPublisher类提供。

翻译自: https://www.javacodegeeks.com/2018/01/java-9-glance.html

javaee概览

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 命令之 source -- 在当前Shell环境中从指定文件读取和执行命令

文章目录一、命令介绍二、命令格式三、命令示例一、命令介绍 source 命令会在当前 Shell 环境中从指定文件读取和执行命令。source 命令通常用于重新执行刚修改的初始化文件&#xff0c;使之立即生效&#xff0c;而不必注销并重新登录。 source 命令&#xff08;从 C Shell 而…

opc调试软件_组态王和三菱OPC软件完美演绎天塔之光

许多朋友因为在学习组态王的过程中因为没有实物PLC而发愁&#xff0c;这里我通过天塔之光实例分享一个三菱OPC软件模拟实物PLC与组态王通信的方法。一、需要软件组态王软件三菱PLC编程软件GX Works2三菱OPC软件MX OPC Configurator二、控制要求主画面如上图所示的天塔灯光&…

jar混淆,防止反编译,Allatori工具混淆jar包

文章目录 Allatori工具简介下载解压配置config.xml注意事项 Allatori工具简介 官网地址&#xff1a;https://allatori.com/ Allatori不仅混淆了代码&#xff0c;还最大限度地减小了应用程序的大小&#xff0c;提高了速度&#xff0c;同时除了你和你的团队之外&#xff0c;任何人…

计算机基础知识学前自测,2011计算机二级C语言学前自测题:DOS的基本操作

DOS的基本操作1.DOS系统启动后&#xff0c;下列文件中常驻内存的是( )。A)DOS.COM B)COMMAND.COMC)DISKCOPY.COM D)SYS.COM2.若当前盘为C盘&#xff0c;在A盘目录\data中只有文本文件test.DAT&#xff0c;A 盘当前目录为根目录&#xff0c;则查看该文件的内容可使用的命令是( )…

string拆分为int_拆分为流

string拆分为int我正在为我工​​作的公司准备正则表达式教程更新。 原始教程创建于2012年&#xff0c;从那时起Java发生了一点变化。 有新的Java语言版本&#xff0c;尽管Java中的正则表达式处理仍不完善&#xff08;nb。它仍使用非确定性FSA&#xff09;&#xff0c;但仍有一…

Linux 命令之 type -- 显示指定命令的类型

文章目录一、命令介绍二、命令格式三、命令类型四、常用选项五、命令示例&#xff08;一&#xff09;查看命令的类型&#xff08;二&#xff09;显示外部命令的绝对路径一、命令介绍 type 命令用来显示指定命令的类型&#xff0c;判断给出的指令是内部指令还是外部指令。 二、…

python 查找算法_python快速查找算法应用实例

文实例讲述了Python快速查找算法的应用&#xff0c;分享给大家供大家参考。具体实现方法如下&#xff1a;import randomdef partition(list_object,start,end):random_choice start#random.choice(range(start,end1))#把这里的start改成random()效率会更高些x list_object[ra…

驾校约车html网站源码,html5首汽约车微信感恩活动页面模板

html5整屏滚动css3特效&#xff0c;各种c3特效&#xff0c;手机端支持各种分辨率&#xff0c;感恩活动微信页面模板下载。资源下载此资源下载价格为4D币&#xff0c;请先登录资源文件列表codedown123-0831-42/css/animate.min.css , 61353codedown123-0831-42/css/reset.css , …

java+解析未知json_在Java中解析JSON时如何忽略未知属性– Jackson @JsonIgnoreProperties注释示例...

java解析未知json使用Jackson API在Java中解析JSON时的常见问题之一是&#xff0c;当您的JSON包含未知属性&#xff08;即您的Java类没有对应于所有JSON属性的所有字段&#xff09;时&#xff0c;该操作将失败。 例如&#xff0c;如果您正在使用REST Web服务中的JSON&#xff0…

双非计算机考研推荐学校传菜电梯,22考研双非院校排名Top100,前3名竟然是这几所!...

原标题&#xff1a;22考研双非院校排名Top100&#xff0c;前3名竟然是这几所&#xff01;大家好&#xff01;这里考个研吧&#xff01;近年来&#xff0c;很多双非高校发展进步很快&#xff0c;实力超过很多末流211大学&#xff01;国家也实行了双一流、学科评估等&#xff0c;…

按压缩格式整理打包(解包)和压缩(解压)命令

文章目录一、zip 格式&#xff08;一&#xff09;使用命令 zip 压缩文件&#xff08;二&#xff09;使用命令 unzip 解压 zip 包二、tar 格式&#xff08;一&#xff09;打包文件&#xff08;二&#xff09;解包 tar 包三、tar.gz 格式方式一&#xff1a;利用已经打包好的tar文…

4线电子围栏安装示意图_知识积累|周界防护-脉冲电子围栏的安装

如今人们对于住宅需求早已今非昔比&#xff0c;不但需要足够大的空间&#xff0c;而且对于住宅所处位置是否交通便利&#xff0c;环境如何&#xff0c;光照情况都有要求&#xff0c;但是最关注的问题还是住宅的安全问题。如今的社会科技发达&#xff0c;不法分子的手段也层出不…

非对称加密 公钥私钥_选择Java加密算法第3部分–公钥/私钥非对称加密

非对称加密 公钥私钥抽象 这是涵盖Java加密算法的三部分博客系列的第3部分。 该系列涵盖如何实现以下功能&#xff1a; 使用SHA–512散列 使用AES–256的单密钥对称加密 RSA–4096 这第三篇文章详细介绍了如何实现非对称的RSA-4096公/私钥加密。 让我们开始吧。 免责声明 …

Linux 命令之 compress -- unix 档案压缩命令

文章目录一、命令介绍二、常用选项三、命令示例&#xff08;一&#xff09;压缩文件&#xff08;二&#xff09;解压文件一、命令介绍 compress 命令使用“Lempress-Ziv”编码压缩数据文件。compress 是一个相当古老的 unix 档案压缩程序&#xff0c;文件经它压缩后&#xff0…

计算机电源风扇维修,电脑电源开关维修和电源风扇加油图解全过程.doc

窗体顶端窗体底端电源开关维修及电源风扇加油图解全过程2010-05-06 17:56:19 来源&#xff1a;计算机故障查询网 浏览&#xff1a;804次-今天一朋友拿了部联想电脑(虽然俺不喜欢,但每个人有自己的爱好,就没说啥)给我,说让我帮他的电脑体检一下,说开不了机于是开展程序化工作,朋…

内部收益率irr_介绍一个神器,内部收益率IRR

内部回报率IRR这个概念&#xff0c;艾米姐在很多地方都讲到了。可以这么说&#xff0c;任何的理财产品&#xff0c;都可以用这个概念来测算一下收益到底如何。听起来IRR确实很强大啊。那它到底是个什么东东呢&#xff1f;今天就来说一说。一、什么是内部收益率IRR&#xff1f;这…

如何在Java中处理ConcurrentModificationException? 在循环中从ArrayList中删除元素时要当心...

从Java中从ArrayList中删除元素时常见的问题之一是ConcurrentModificationException。 如果您对索引使用经典的for循环或增强的for循环&#xff0c;并尝试使用remove()方法从ArrayList中remove()元素&#xff0c;则将获得C oncurrentModificationException但如果使用Iterator的…

Linux 命令之 zip -- 压缩文件

文章目录一、命令介绍二、常用选项三、命令示例&#xff08;一&#xff09;压缩指定目录及其包含的内容&#xff08;二&#xff09;压缩指定目录及其包含的内容&#xff0c;并选择压缩效率一、命令介绍 zip 命令可以将一个或多个文件放入一个压缩存档中&#xff0c;文件经它压…

南安职业中专学校计算机专业,南安职专:国家级重点职业中专学校

原标题&#xff1a;南安职专:国家级重点职业中专学校学校创办于1984年&#xff0c;现有教职工252人&#xff0c;在校生4152人。2004年被首批重新确认为国家级重点职业中专学校&#xff0c;2012年9月被确认为国家中等职业教育改革发展示范学校建设项目校。2016年1月份被确认为福…

python eel 多线程_Python 基础

input() 用于输入print() 用于输出数据类型:1、整数 、浮点数‘ / ‘ 表示除 得出的结果一定是个浮点型.‘ // ‘ 表示除 得出的结果一定是整数.(如果是小数会自动取整)‘ % ‘ 表示除 取余数(自动取得小数点后面的数)2、字符串(‘’ / “”)可以使用 ‘ \ ‘ 转义, r表示内部的…