NetBeans 9抢先体验

Java 9即将来临,NetBeans 9也即将来临。在本文中,我们将看到NetBeans 9 Early Access为开发人员提供的支持,以帮助他们构建Java 9兼容的应用程序。

Java 9提供了许多(大约90种) 新功能,包括Modules和JShell,Read-Eval-Print-Loop(REPL)等。 您可以在本文末尾的参考资料中找到更多信息,尤其是有关NetBeans 9支持JDK 9的链接 。

在本文中,我们将学习如何:

  1. 从源代码下载并构建Java 9 EA
  2. 从源代码下载并构建NetBeans 9 EA
  3. 使用NetBeans 9 EA中的JShell REPL
  4. 使用NetBeans 9 EA创建和构建模块以及它们之间的依赖关系,使我们的生活更轻松

1.构建OpenJDK 9 EA

OpenJDK是任何JDK增强建议 (JEP)甚至Java规范请求 (JSR)的参考实现。 您可能有很多原因,为什么要从源代码构建它,而不下载预构建的二进制文件之一 ,例如:

  • 强制您从源代码构建开源项目的公司政策
  • 您希望获得最新的早期访问OpenJDK
  • 您想要为您的特殊平台构建

当然,您可以通过下载预构建的二进制文件来继续本文。 但是,如果您想学习如何构建JDK 9,请继续阅读。 构建自己的JDK映像具有许多优势,例如,您不需要安装任何东西或进行修改,例如Windows注册表或MacOS上的Java Preferences面板都可以破坏当前的默认JDK(请参见例如本文 )。 可执行文件将始终在同一位置创建,并且通过更新存储库并重新构建源代码,您始终可以拥有最新版本。

您可以下载最新的OpenJDK 9二进制文件此页面。 资料可以在Mercurial资料库中找到。 例如OpenJDK 9仓库在这里 ; 如果希望参与项目,那么Jigsaw回购项目将包含模块化实现的主要内容。 在下面,您将获得有关如何构建OpenJDK 9的一些技巧。

  1. 克隆JDK 9 Master mercurial存储库。
  2. 阅读READMEREADME-builds.html文件以获取更多说明。
  3. 开始构建之前的下一步是执行: bash get_source.sh./get_source.sh如果您的shell已经是bash)。 在每次更新后调用此命令非常重要。 原因是hg update仅更新主存储库。 OpenJDK包含许多需要更新的Mercurial存储库。 这可以通过get_source.sh命令来完成。
  4. ./configure --disable-warnings-as-errors
  5. sudo make all

上面的命令构建了OpenJDK的最新版本。 如果您希望构建OpenJDK的早期版本,则需要遵循以下提示:

  1. hg up [tag]例如jdk-9+147
  2. cd corba
  3. hg up [tag]例如jdk-9+147
  4. 对目录重复步骤2和3: hotspot, jaxp, jaxws, jdk, langtools, nashorn
  5. ./configure --disable-warnings-as-errors
  6. sudo make clean
  7. sudo make all

二进制文件是在build/<platform_dir>/jdk中创建的,例如,如果您在build/macosx-x86_64-normal-server-release/jdk使用Mac。

2.构建和配置NetBeans 9 EA

您可以从http://wiki.netbeans.org/ JDK9Support下载具有JDK 9支持的最新NetBeans或从以下来源进行构建:

  1. hg clone http://hg.netbeans.org/main
  2. cd main
  3. hg clone http://hg.netbeans.org/main/contrib
  4. cd ..
  5. ant

二进制文件在nbbuild/netbeans创建。 将其配置为与JDK 8或JDK 9 EA( etc/netbeans.conf )一起运行。 jshell ,要启用jshell ,您需要使用JDK 9 EA设置NetBeans 9。 因此,编辑etc/netbeans.conf指向您在步骤1中构建的JDK 9 EA:

netbeans_jdkhome="<path to OpenJDK 9 EA>/build/<platform_dir>/jdk"

请备份此文件,因为下次构建NetBeans时,它将被覆盖,因此您必须再次进行此修改。

通过发出以下命令来启动netbeans: bin/netbeansbin\netbeans.exe具体取决于您的平台。 通过工具 | NetBeans将最新的JDK 9 EA构建注册为Java平台Java 平台| 添加平台 (参见图1),然后选择在步骤1中构建的OpenJDK 9 EA。

图1 –将JDK 9 EA平台添加到NetBeans 9 EA

3. NetBeans 9 EA中的JShell支持

如果使用JDK 9实现启动NetBeans 9,则可以从菜单|工具|菜单中访问JShell 打开Java Platform Shell 。 JShell的工作原理与命令行相同,此外,NetBeans快捷方式也可以使用它(例如sout --> (tab) )。 您可以在参考资料中阅读有关JShell的更多信息。

图2-NetBeans 9 EA中的JShell

图2 – NetBeans 9 EA中的JShell。

4. NetBeans 9 EA中的模块支持

NetBeans 9 EA提供了许多好处,可以帮助您进行模块化项目。 在继续之前,必须在“ 工具” |“设置”中设置JDK 9 EA平台。 Java 平台| 添加平台并选择您在步骤1中构建的OpenJDK 9 EA二进制文件的路径。

要将现有项目转换为模块,您需要执行两项任务:

  1. 在项目属性中将项目设置为与JDK 9兼容:
    1. Libraries中,Java Platform设置为JDK 9 EA Java平台(图3)。
    2. Sources中,Source / Binary Format设置为JDK 9 (图4)。
  2. 在您的项目中添加一个Java模块信息(即模块描述符 module-info.java )(见图5):
    1. 档案| 新档案…| Java(类别)| Java模块信息(文件类型)
图3-将Java平台设置为JDK 9 EA

图3 –将Java平台设置为JDK 9 EA

图4-Java源

图4 –将Java Sources设置为JDK 9

图5-添加Java模块信息

图5 –添加Java模块信息

module-info.java必须始终位于NetBeans 9中Java项目的根目录中。这是NetBeans 9中的一项限制,而不是JDK 9中的一项限制。唯一的例外是,我们可以在一个目录中包含多个module-info.java文件。一个Java项目就是我们进行单元测试的时候。 您可以在Test Packages添加module-info.java文件。

但是,让我们通过在NetBeans 9 EA中实现项目Jigsaw的快速入门指南来了解NetBeans 9 EA模块的支持。

我的第一个使用NetBeans 9的模块化应用程序

第一个示例是名为com.greetings的模块,该模块仅显示“ Greetings!”。 该模块包含两个源文件:模块声明( module-info.java )和主类。

按照约定(模块名称可以是Java限定的标识符),模块的源代码位于模块名称的目录中(在本例中为com.greetings ),即使这不是必需的。

通过执行以下步骤在NetBeans中创建一个新的Java项目:

  1. 档案| 新项目…
  2. 选择Java (类别)和Java应用程序 (项目),然后单击Next。
  3. 在下一页中,选择一个“项目位置”并输入“ com.greetings”作为项目名称,这是因为遵循本教程的约定,但是也可以使用常规的Java项目名称,例如“ Greetings”。 将主类重命名为com.greetings.Main 。 点击完成

您应该看到一个名为com.greetings的Java项目,并且在其中包含com.greetings.Main类,其中包含main()方法。 像这样修改它:

com.greetings.Main

package com.greetings;/** @author javacodegeeks */
public class Main {/** @param args the command line arguments */public static void main(String[] args) {System.out.println("Greetings!");}
}

要将Java Project转换为模块, module-info.java按照前面所述添加module-info.java ,即,右键单击项目名称,然后选择File | 新档案…| Java(类别)| Java模块信息(文件类型)

在项目的根包中创建一个空的module-info.java 。 按照Jigsaw教程重命名,如下所示:

com.greetings.module-info.java

module com.greetings {
}

您必须清理并构建项目才能使模块重命名生效并成功运行。 您应该看到消息“问候!” 在输出窗口中。
使用NetBeans,您无需关心命令行语法以及javacjava命令的参数。 这些由NetBeans IDE负责。

添加依赖项

第二个示例更新模块声明,以声明对模块org.astro的依赖。 模块org.astro导出API包org.astro

按照上一org.astro的步骤创建一个名为org.astro的新Java项目。 这次不要创建Main Class。 创建项目后,右键单击它,然后选择“ 新建” |“新建”。 Java类…输入World作为类名,输入org.astro作为包名,然后单击Finish 。 像这样更新新创建的类:

org.astro.World.java

package org.astro;/** @author javacodegeeks */
public class World {public static String name() {return "world";}
}

添加module-info.java就像我们对以前那样com.greetings

org.astro.module-info.java

module org.astro {
}

不要忘记清理和构建模块重命名才能生效。

现在,我们需要从com.greetings模块到org.astro模块添加一个依赖关系,以便使用其方法World.name() 。 但是在此之前, org.astro必须导出包含此方法的软件包。 这两个动作都需要在两个模块的module-info.java文件中进行。 NetBeans 9为您提供了有关如何执行操作的有用提示。

  1. 打开org.astromodule-info.java并在方括号内键入Ctrl-Space 。 如示于图6.选择一个弹出菜单将出现,显示可用的命令exports并通过键入继续org.astro它是包名到出口。 NetBeans在键入时为您提供提示。 保存module-info.java您会注意到“ 项目”选项卡中软件包的锁定图标变为打开的锁定。
  2. 打开com.greetingsmodule-info.java并在括号内按照上述步骤输入requires org.astro的命令,这一次引用的是模块名称而不是程序包名称(另一个原因是为什么Jigsaw项目的快速入门指南并不是那么成功,因为它难以区分包和模块名。 但是,NetBeans抱怨module not found错误消息module not found 。 为了使NetBeans能够找到该模块,还需要执行一步。
  3. 右键单击com.greetings Java项目的Libraries文件夹, com.greetings从弹出菜单中选择“ 添加项目 ”。 选择org.astro Java项目,然后单击添加项目JAR文件 。 错误消失了。 另一种执行相同操作的方法是右键单击项目com.greetings然后从弹出菜单中选择“ 属性 ”。 在“项目属性”对话框中,单击“ ”类别,然后单击“ 模块路径”旁边的+号。 选择“ 添加项目”,然后选择“ org.astro Java项目”,然后单击“ 添加项目JAR文件” 。 请记住,如果您尝试添加循环依赖关系(例如,从`org.astro`到com.greetings ),则NetBeans将显示一个对话框,显示以下消息: 无法添加循环引用 (请参见图7)。
  4. 像这样修改Main.main()方法,然后清理并构建两个模块。
图6-模块信息命令

图6 –模块信息命令

图8-循环依赖性错误

图7 –循环依赖性错误

com.greetings.Main.java

package com.greetings;
import org.astro.World;
/** @author javacodegeeks */
public class Main {/** @param args the command line arguments */public static void main(String[] args) {System.out.format("Greetings %s!%n", World.name());}
}

当您粘贴新的System.out.format(...)语句时,NetBeans会识别World类,并建议添加import语句。 这是唯一可能的,因为您已经更新了两个模块的module-info.java文件,如下所示:

com.greetings.module-info.java

module org.astro {exports org.astro;
}

org.astro.module-info.java

module com.greetings {requires org.astro;
}

NetBeans 9 EA为您提供了依赖性的可视化表示(模块图)。 只需在org.greetings module-info.java编辑器中单击Graph按钮,即可看到模块依赖关系的漂亮图表,如下图所示。

图8-模块图

图8 –模块图

运行com.greetings模块以查看输出: Greetings world! 如预期的那样。

与项目Jigsaw的原始快速入门指南进行比较,以了解使用NetBeans IDE节省了多少键入内容。

包装模块

使用NetBeans打包模块非常容易。 右键单击项目com.greetings然后从弹出菜单中选择“ 属性 ”。 在Project Properties对话框(图9)中,单击Build下的Packaging类,并选择Create JLink distributionCreate Launcher ,然后单击OK 。 下次清洁和构建NetBeans时,将在com.greetings Java项目的dist文件夹内生成Java运行时映像,其中仅包含运行com.greetings所需的JDK模块(即,仅java.base模块)。 无需记住jlink命令的语法。

图9-包装模块

图9 –包装模块

Java模块化项目

正如我们一开始提到的,NetBeans 9每个Java项目仅允许一个模块。 但是,使用Java模块化项目,可以在这个特殊的Java项目中定义许多模块。 我们将使用Java模块化项目重新实现先前的模块。 这是一个基于ant的项目,其中包含多个模块并立即进行编译。

  1. 档案| 新项目…
  2. 选择Java (类别)和Java Modular Project (项目)(图10),然后单击Next。
  3. 输入ModularGreetings作为项目名称,然后单击完成。
  4. 右键单击新创建的项目,然后从弹出菜单中选择“ 新建模块 ”。
  5. 输入com.greetings作为模块名称,然后单击Finish 。 NetBeans会为此模块打开module-info.java文件。
  6. 重复上一步以创建org.astro模块。
  7. 如4.2中所述在两个模块之间创建依赖关系
  8. 在每个模块的classes中创建(或从4.2中创建的先前模块中复制)软件包。
  9. 清洁并建造。 无需添加org.astro到的模块路径com.greetings ; 它是自动完成的。
  10. 运行项目以查看正确的输出: Greetings world!
图10-新的Java模块化项目

图10 –新的Java模块化项目

图11-Java模块化项目

图11 – Java模块化项目

您会看到Java Modular Project具有许多优点,例如您不需要将其他项目显式添加到Module路径。 当您更新module-info.java时,将自动完成此操作。

服务

松散耦合是指每个组件对其他独立组件的定义了解很少或不了解的系统。 这使得各个组件可以独立更改,而不会影响其他组件。

但是,让我们描述一个示例,以深入了解《 快速入门指南》的详细信息。

假设您有一个提供服务的提供者。 例如,这可以是AlertService (提供各种系统或应用程序警报), CoordinatesProvider (提供各种坐标系统,例如纬度/经度,GEOREF,UTM等), AlgorithmProvider (提供针对问题的各种算法解决方案)等为了实现松散耦合,您可以为调用程序类提供一个接口,以隐藏其背后的实际实现。 调用者(或服务使用者)类不需要知道任何实际的实现。 他们只需要知道如何访问相关方法即可。 然后,在运行时以某种方式将实现提供给调用方类。 这样,只要Provider接口不更改,实际的实现就可以在任何时候更改而无需调用方类知道。

有多种方法可以实现松散耦合。 这通常是由服务提供商完成的。 服务定位器设计模式提供了对服务的全局访问点,而无需将调用者(服务使用者)耦合到实现该服务的具体类上。 例如, Spring使用依赖注入 ( 控制反转的一种形式),NetBeans的RCP 模块化API使用Lookups和ServiceProviders等。Jigsaw使用Java 6中的ServiceLoader 。服务使用者和服务提供者类可以驻留在不同的模块中。

从拼图快速入门指南 ,模块com.socket提供服务NetworkSocketProviderNetworkSocket秒。 在两个不同的模块中提供了此服务的两种实现: org.fastsocketorg.smartsocket 。 我们的服务使用者模块com.greetings仅需要依赖com.socket服务提供者模块, com.greetings需要依赖服务实现模块。

图12-服务提供商

图12 –服务提供商

让我们看看如何实现这一目标。 在NetBeans 9 EA中,如我们之前com.socket ,创建一个新的Java Project com.socket ,而不提供Main类。

如《 快速入门指南》中所述,创建两个类com.socket.NetworkSocketcom.socket.spi.NetworkSocketProvider ,添加新的module-info.java以将项目转换为Java 9模块,并将这两个包导出到使用者类:

com.socket.module-info.java

module com.socket {exports com.socket;exports com.socket.spi;uses com.socket.spi.NetworkSocketProvider;
}

最后一条语句声明此模块向使用者提供com.socket.spi.NetworkSocketProvider服务。 不要忘记清理并构建此模块,以使更改生效。

接下来,让我们创建org.fastsocket模块。 与以前一样,按照快速入门指南中的描述创建两个类org.fastsocket.FastNetworkSocketorg.fastsocket.FastNetworkSocketProvider ,添加一个新的module-info.java以将项目转换为Java 9模块,并为com.socket添加依赖项com.socket模块:

org.fastsocket.module-info.java

module org.fastsocket {requires com.socket;provides com.socket.spi.NetworkSocketProviderwith org.fastsocket.FastNetworkSocketProvider;
}

最后一条语句提供com.socket.spi.NetworkSocketProvider服务提供程序的实现。 请注意,这个模块出口任何包!

但是,该项目包含编译错误。 你能说出为什么吗?

我们需要将com.socket添加到modulepath中(如果您不记得该怎么做,请参考本文前面的内容)。 清理并构建以确保没有错误。

您可以重复上述步骤以类似的方式创建org.smartsocket ,但是,快速入门指南并没有这样做,因此,您可以根据需要创建自己的实现。

最后,创建消费者com.greetings Java项目(使用另一个目录不乱用的com.greetings模块我们在第一章4.1和4.2创建)与com.greetings.Main类,从的内容复制快速入门指南 ,添加一个新的module-info.java ,将项目转换为Java 9模块,并向com.socket添加一个依赖com.socket

com.greetings.module-info.java

module com.greetings {requires com.socket;
}

确保您添加了模块com.socket并完成。 清理并构建,然后运行com.greetings ,您将看到一个错误:

运行时异常

Exception in thread "main" java.lang.RuntimeException: No service providers found!at com.socket/com.socket.NetworkSocket.open(NetworkSocket.java:19)at com.greetings/com.greetings.Main.main(Main.java:8)

为什么? 我们确实做了《 快速入门指南》中提到的内容。 NetBeans Java项目要求您在模块路径中添加org.fastsocket (然后将其自动添加到module-info.java ),然后该异常消失:

org.fastsocket.FastNetworkSocket

class org.fastsocket.FastNetworkSocket

作为练习,您可以使用Java模块化项目重复上述操作。 在这里,你不需要添加服务提供者实现模块(如org.fastsocket )到模块路径com.greetings

但是它是如何工作的呢? 拼图使用ServiceLoader定位各种服务提供者实现:

服务加载器

ServiceLoader<NetworkSocketProvider> sl= ServiceLoader.load(NetworkSocketProvider.class);
Iterator<NetworkSocketProvider> iter = sl.iterator();

sl.iterator()将遍历org.fastsocket.FastNetworkSocketProvidercom.smartsocket.SmartNetworkSocketProvider (如果已实现)。

在后台, ServiceLoader创建一个提供程序配置文件,该文件存储在服务提供程序的JAR文件的META-INF/services目录中。 配置文件的名称是服务提供者的完全限定的类名称,其中名称的每个组成部分均以句点( . )分隔,而嵌套的类则以美元符号( $ )分隔。 换句话说, ServiceLoader在模块的build/classes/META-INF/services/文件夹(或dist/provider.jar )内创建一个文本文件package.Provider ,其中包含实现类的标准名称,例如package.ProviderImpl

在我们的示例中, com.socket/build/classes/META-INF/services/包含文本文件com.socket.spi.NetworkSocketProvider ,其中包含实现类org.fastsocket.FastNetworkSocketProvider (和com.smartsocket.SmartNetworkSocketProvider标准名称com.smartsocket.SmartNetworkSocketProvider如果已实现)。

至少,如果使用Java 6 ServiceLoader ,这应该是“幕后”实现! 不幸的是,Java 9修改了ServiceLoader的实现。

Java 6 ServiceLoader具有许多限制:

  • 它不是动态的(您无法在运行时安装/卸载插件/服务)
  • 它会在启动时加载所有服务(因此需要更长的启动时间和更多的内存使用量)
  • 无法配置; 有一个标准的构造函数,它不支持工厂方法
  • 它不允许进行排名/排序,即我们无法选择要首先加载的服务(服务的排序是在发现时进行的)

此外,Java 9对Java 6 ServiceLoader进行了如下修改:

  • 没有相关服务; 新的基于模块的服务定位器没有相对行为
  • 服务的订购(如发现)丢失
  • 模块路径上的所有服务接口和实现均被展平为单个全局名称空间
  • 服务加载没有可扩展性/可定制性; 服务层提供者必须预先提供可用服务的固定映射
  • 多站点声明; 每个使用服务的模块还必须在模块描述符中声明正在使用该服务; 没有全局的全层服务注册表

换句话说,如果您搜索com.socket/build/classes/META-INF/services/com.socket/dist/com.socket.jar/META-INF/services/您将一无所获。

NetBeans RCP改为提供ServiceProvider ,它没有上面提到的ServiceLoader的缺点。 它是动态的,因此您可以在应用程序运行时插入/拔出模块,它不会在启动时加载所有服务,并允许您设置优先级(使用@ServiceProvider批注的position属性)。 不幸的是,它不适用于拼图。

5. NetBeans的进一步改进

要使程序包可用于其他模块,必须编辑module-info.java并添加一个将程序包名称作为参数传递的exports语句。 这将导致包图标更改为具有打开锁的图标,而不是已锁定的图标。

一个不错的捷径是能够右键单击一个包,然后选择一个动作Export Package ,如下图所示,该操作将相应地自动修改module-info.java ,而无需键入export命令。

图13-NetBeans的改进;添加导出包菜单项

图13 – NetBeans的改进; 添加导出包菜单项

NetBeans RCP 模块API (NetBeans胖客户端平台随附的API)中已经存在此功能。

在由许多模块组成的项目中,通常很难找到依赖项存在于哪个模块中。 一个很好的补充就是能够在整个模块(和/或库模块)中搜索我们要查找的类。 NetBeans RCP 模块API (NetBeans胖客户端平台随附的API)中已经存在类似的功能。

当由于NetBeans找不到依赖项而遇到错误时,单击提示blob将打开一个对话框,开发人员可以在其中键入所需的类,如下图所示,然后选择适当的模块。 当开发人员请求将模块依赖项添加到模块路径时(例如,通过右键单击Libraries ),可以访问相同的对话框。

图14-NetBeans的改进;搜索模块的依赖关系

图14 – NetBeans的改进; 搜索模块的依赖关系

最后,可以将一个新模块添加到Java Modular Project中,但是无法删除模块,尽管至少要编写这些行。 这是一个固定的EA错误。

NetBeans 9 EA仍在大量开发中,并且尚未通过官方测试(也称为NetCat),因此在此阶段会遇到一些错误或奇怪的行为是正常的。

六,结论

在本文中,我们了解了NetBeans 9 EA如何支持JDK 9 EA并简化了开发人员的工作。 作为开发人员,您无需记住如何使用模块路径来构建和执行Java模块的细节,或者如何jlink命令的细节。 NetBeans 9隐藏细节。 JShell也很好地集成了。 当然,某些改进可以使开发人员的生活更加轻松,但是这些改进将在将来的NetBeans版本中或作为插件出现。

我们看到了可以用来创建模块化Java应用程序的两种项目。 我们看到了可以在module-info.java内部使用的五个可用命令中的四个命令的使用: exports, requires, usesprovidesopens允许其他模块使用反射来访问您打开的包中的类型。

普通模块中的特定程序包可以被“打开”,因此只有该程序包可在运行时进行深度反射:

com.greetings.module-info.java

module com.greetings {opens com.greetings;
}

一些Java框架和工具在运行时严重依赖反射来访问未导出模块的代码。 它们提供诸如依赖项注入,序列化,Java Persistence API的实现,代码自动化,调试等功能。示例包括Spring和Hibernate。 这些框架和库不了解您的应用程序模块,但是它们需要访问模块的类型和私有成员,这打破了JDK 9中强封装的前提。还可以打开整个模块以进行反射,例如:

com.greetings.module-info.java

open module com.greetings {requires com.socket;
}

opensexports进行比较, exports语句可让您在编译时和运行时仅访问指定包的公共API,而opens语句可让您在运行时使用反射来访问指定包中所有类型的公共和私有成员。

与拼图游戏配合使用时,玫瑰花还不是全部。 专家社区还没有接受拼图游戏,并且对他们遇到的许多严重缺陷有很多担忧。

7.参考

  1. NetBeans 9 EA
  2. NetBeans 9 EA JDK 9支持
  3. Sitepoint Java 9终极指南
  4. JDK 9功能完整 ,JavaCodeGeeks
  5. Java杂志 ,2017年7月至8月
  6. Java 9系列: JShell ,Voxxed
  7. Java 9 系列 :HTTP / 2 客户端 ,Voxxed
  8. Java 9系列: JVM ,Voxxed
  9. Java 9系列:HTML5和 Javadoc ,Voxxed
  10. Java 9 系列 : 并发 更新 ,Voxxed
  11. Java 9系列:变量 句柄 ,Voxxed
  12. Java 9系列:封装大多数内部 API ,Voxxed
  13. Java 9系列:多发行JAR 文件 ,Voxxed
  14. Java 9 系列 : 分段 代码 缓存 ,Voxxed
  15. Java 9系列: 集合的 便利工厂方法 ,Voxxed
  16. 拼图中的严重缺陷
  17. Bateman A.(2016),“为JDK 9做准备”, JavaOne 。
  18. Bateman A.(2016年),“模块化开发简介”, JavaOne 。
  19. Bateman A.和Buckley A.(2016),“高级模块化开发”, JavaOne 。
  20. Buckley A.(2016),“模块和服务”, JavaOne 。
  21. Buckley A.(2016年),“ Project Jigsaw:The Hood”, JavaOne 。
  22. Bateman A.,Chung M.,Reinhold M.(2016年),“ Project Jigsaw Hack Session”, JavaOne 。
  23. Deitel P.和Deitel H.(2017年),《 Java 9 for Programmers》,第四版,Deitel。
  24. Evans,B.(2016),“ Java 9模块的早期观察” ,《 Java Magazine》 ,第26期,1-2月,第59-64页。
  25. Gupta A.(2015年),《 JDK 9 REPL:入门》 ,JavaCodeGeeks
  26. 慢跑TM。 (2016), 学习模块化Java编程 ,Packt。
  27. Mak S.和Bakker P.(2016年), Java 9 Modularity, O'Reilly(早期发行)
  28. Reinhold M.(2016), 问题模块反射访问 , Voxxed
  29. Sharan K.(2017年),《 Java 9公开供早期采用和迁移》 ,Apress。
  30. Verhas P.(2017年),《 Java 9示例编程》 ,Packt。
  31. Zhitnitsky A.(2015), Java 9抢先体验:与JShell进行动手实践– Java REPL ,JavaCodeGeeks。

翻译自: https://www.javacodegeeks.com/2017/07/netbeans-9-early-access.html

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

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

相关文章

块裁剪后的矩形边界如何去掉_手持拍摄画面太抖?这节课教你如何快速稳定抖动的画面...

手持相机进行拍摄&#xff0c;画面会有较为明显的抖动&#xff0c;这节课就教大家如何稳定视频画面。素材导入到PR后&#xff0c;为素材添加变形稳定器效果&#xff0c;软件会自动开始分析。当前素材上方会显示在后台分析&#xff0c;这时候我们可以剪辑其他部分&#xff0c;并…

怎么把空字符串去掉_Python知识点字符串转整数需注意

↑↑↑关注后"星标"简说Python人人都可以简单入门Python、爬虫、数据分析简说Python严选 来源&#xff1a;简说Python 作者&#xff1a;老表One old watch, like brief python大家好&#xff0c;我是老表&#xff5e;Python知识点系列&#xff0c;学习了记得点赞、…

android-x86 镜像iso下载_Windows 10(1909)最新12月更新版MSDN官方简体中文原版ISO镜像下载+激huo工ju...

微软已于11月中旬开始大规模推送Windows 10操作系统的最新版本1909。此次更新官方未放出具体更新日志&#xff0c;但没有太多大功能更新&#xff0c;主要还是“修修补补”为主。现在&#xff0c;为大家带来本次官方最新原版ISO镜像下载&#xff0c;具体内部版本号为18363&#…

32查运行内存的map文件_Spark Shuffle调优之调节map端内存缓冲与reduce端内存占比

本文首先介绍Spark中的两个配置参数: spark.shuffle.file.buffer map端内存缓冲 spark.shuffle.memoryFraction reduce端内存占比很多博客会说上面这两个参数是调节Spark shuffle性能的利器&#xff0c;实际上并不是这样的。以实际的生产经验来说&#xff0c;这两个参数没…

odoo self.ensure_one()

源码&#xff1a; def ensure_one(self): """ Verifies that the current recorset holds a single record. Raises an exception otherwise. """ try: # unpack to ensure there is only one value is faster than len when…

模板 字段_劲爆新功能:轻流文字识别(OCR)功能支持自定义识别模板啦

Hi&#xff0c;又和大家见面啦&#xff5e;前段时间我们的文字识别(OCR)功能推出后&#xff0c;由于只支持系统提供的固定识别模板&#xff0c;很多客户跟我们反馈说&#xff1a;希望可以自定义识别模板&#xff01;现应大家的要求&#xff0c;轻流「文字识别(OCR)」的「自定义…

Java 9中的进程处理

一直以来&#xff0c;用Java管理操作系统进程都是一项艰巨的任务。 这样做的原因是可用的工具和API较差。 老实说&#xff0c;这并非没有道理&#xff1a;Java并非出于此目的。 如果要管理OS进程&#xff0c;则可以使用所需的Shell&#xff0c;Perl脚本。 对于面临更复杂任务的…

拼音缩写是啥意思_NMSL?AWSL?这些拼音缩写到底是啥意思?

我绝对没有在骂你们&#xff0c;我只是单纯的举个例子而已。我们在网上冲浪时经常可以看到这些几个字母组成的拼音缩写&#xff0c;对于知道这些梗的人一眼就能GET到&#xff0c;但对于不明白的人来说猜来猜去也猜不出啥意思。所以今天就来给大家科普几个经常出现的拼音缩写&am…

python利用自动识别写模块_序章:资料预处理(python3.6 可用fortran unformatted sequencial data读取模块)...

首先我只是一个接触Python约半年的菜鸟&#xff0c;开这一个专栏的目的主要是记录自己所学&#xff0c;以及实践的一些有用的东西&#xff0c;顺便分享一些自己写的公用代码段以方便具有同样想法的朋友。 既然是序章我就多写一些吧&#xff0c;我本人对人工智能在气象方面的应用…

python蟒蛇代码_011 实例2-Python蟒蛇绘制

一、"Python蟒蛇绘制"问题分析 1.1 Python蟒蛇绘制 用程序绘制一条蟒蛇 貌似很有趣&#xff0c;可以来试试 先学会蟒蛇绘制&#xff0c;再绘朵玫瑰花送给TA 设计蟒蛇的基本形状&#xff1a;问题1: 计算机绘图是什么原理&#xff1f; 一段程序为何能够产生窗体&#x…

bjd luts_BJD娃娃背后的圈层文化:一个“成品娃”拍出22万元天价!

■ 作者 黑马君 | 黑马品牌(ID&#xff1a;heimapinpai)现如今“Z世代”已经成为品牌营销中不可忽略的一个关键词&#xff0c;作为消费升级浪潮的主力军&#xff0c;他们早已成为品牌重点目标人群。与90后、80后不同&#xff0c;Z世代成长于互联网迅猛发展的时代&#xff0c;追…

qtcreator版本_【IDE】ROS开发环境之Qt Creator的安装与配置

可以用于ROS开发的IDE很多(可以参考【工具合辑】ROS工程师都在用什么IDE开发呢&#xff1f;用哪种IDE开发更加高效呢&#xff1f; )&#xff0c;ROS的调试依赖环境变量&#xff0c;与外部程序有通讯&#xff0c;因此要求启动IDE的时候加载ROS环境参数&#xff0c;其他方面并无太…

java线程死锁_Java并发:隐藏线程死锁

java线程死锁大多数Java程序员熟悉Java线程死锁概念。 它本质上涉及2个线程&#xff0c;它们彼此永远等待。 这种情况通常是平面&#xff08;同步&#xff09;或ReentrantLock&#xff08;读或写&#xff09;锁排序问题的结果。 Found one Java-level deadlock:"pool-1-t…

空间滤波_第三章 灰度变换与空间滤波-(六)锐化空间滤波器之非锐化掩蔽

知识使人自由&#xff0c;印刷术使知识自由。按照书中的顺序&#xff0c;我们插入一章非微分模式下的锐化的方法&#xff0c;非锐化掩蔽。这种方法在印刷术和出版界已经用了好多年了&#xff0c;具体的过程&#xff1a;模糊原图像从原图像中减去模糊图像&#xff08;产生的差值…

go语言io reader_【已解决】go语言中如何使用io的MultiWriter

【背景】折腾&#xff1a;期间&#xff0c;需要去搞懂&#xff1a;如果新建和设置MultiWriter。【折腾过程】1.参考&#xff1a;去看看&#xff1a;2.然后去试试代码&#xff1a;var filenameOnly stringfilenameOnly GetCurFilename()fmt.Println("filenameOnly", …

golang 包含文本_Golang教程之Web篇(七)

首先&#xff0c;大家一起思考一个问题&#xff1a;何为Web编程&#xff1f;严格来说&#xff0c;这只是一个叫法&#xff0c;并没有学术上的定义&#xff0c;但是一般大家都说到web都是指浏览器相关&#xff0c;所以大家一般说的web开发要么是PC Web要么就是手机Web&#xff0…

delphi switch语句例子_Java 14 祭出增强版 switch,真香!!

Java14&#xff1a;栈长&#xff0c;我还有机会吗&#xff1f;栈长&#xff1a;必须有&#xff01;今天说下switch&#xff01;关注Java技术栈的朋友应该都知道&#xff0c;switch 在 JDK 12 中进行增强了&#xff0c;并且在 JDK 12/13 中一直是预览特性&#xff0c;刚出来的时…

sqoop 导入到hive字段全是null_Sqoop 一点通

sqoop 是什么&#xff1f;sqoop 主要用于异构数据&#xff1a;1. 将数据从hadoop&#xff0c;hive 导入、导出到关系型数据库mysql 等;2. 将关系型数据库 mysql 中数据导入、导出到 hadoop 、hve 。sqoop 版本说明sqoop 1 版本主要从1.4.0 到 1.4.7&#xff1b;sqoop 2 版本主要…

php使用pdo操作mysql数据库实例_php使用PDO操作MySQL数据库实例_PHP

本文实例讲述了php使用PDO操作MySQL数据库的方法。分享给大家供大家参考。具体分析如下&#xff1a;PDO是mysql数据库操作的一个公用类,我们不需要进行自定类就可以直接使用pdo来操作数据库,但是在php默认配置中pdo是未开启所以我们必须先在php.ini中开启它才可以使用,这里来详…

雅虎yql_从RSS Feed和YQL创建数据表

雅虎yqlYahoo Query Language&#xff08; YQL &#xff09;是一种查询语言&#xff0c;例如SQL。 使用YQL&#xff0c;我们可以跨Web服务 查询 &#xff0c; 过滤和联接数据。 YQL也可以阅读RSS feed。 响应可以是JSON或XML。 雅虎提供了一个YQL控制台&#xff0c;用于调试…