netbeans 9_NetBeans 9抢先体验

netbeans 9

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

Java 9提供了许多(大约90种) 新功能,包括模块和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映像具有许多优点,例如,您不需要安装任何东西或进行修改,例如,MacOS上的Windows注册表或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应用程序 (项目)”,然后单击“ 下一步”。
  3. 在下一页中,选择一个“项目位置”并输入“ com.greetings”作为项目名称,这是因为遵循本教程的约定,但是也可以使用常规的Java项目名称,例如“ Greetings”。 将Main Class重命名为com.greetings.Main 。 点击完成

您应该看到一个名为com.greetings的Java项目,并且在其中包含一个包含main()方法的com.greetings.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项目转换为模块, module-info.java按照前面所述添加module-info.java ,即,右键单击项目名称并选择File | 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),“拼图项目:引擎盖下的项目”, 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

netbeans 9

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

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

相关文章

同一个ip能否两次加入组播_组播IGMPv1/v2/v3精华知识汇总

闲言少叙&#xff0c;直奔主题&#xff0c;开说之前先做点铺垫&#xff0c;回顾一下网络的基础知识。D类地址划分回顾组播是IPv4地址分类中的D类&#xff0c;我们回顾一下IPv4的地址划分A类&#xff1a;首bit0&#xff0c;0-127网段&#xff0c;网络掩码8&#xff0c;其中0.0.0…

弹窗要打开或保存来自_如何让 PopClip 支持印象笔记客户端:保存到印象笔记amp;高亮文字...

自从印象笔记品牌独立并发布新APP后&#xff0c;Mac系统下很多工具不再支持与印象笔记客户端进行联动&#xff0c;PopClip 就是其中之一。目前 Popclip 官方并未将印象笔记加入到插件的支持中&#xff0c;不过我们可以手动修改来解决这个问题。Popclip 之所以不支持新版本的印象…

vue 混入对象_特性和混入不是面向对象的

vue 混入对象让我立刻说&#xff0c;我们将在这里讨论的功能是那些迫切需要进行放线手术的人带给面向对象编程的纯粹的毒药 &#xff0c;就像David West在他的《 Object Thinking》一书中所建议的那样。 这些功能具有不同的名称&#xff0c;但是最常见的是traits和mixins 。 我…

glup node 内存不够_Redis:内存被我用完了!该怎么办?

介绍Redis是一个内存数据库&#xff0c;当Redis使用的内存超过物理内存的限制后&#xff0c;内存数据会和磁盘产生频繁的交换&#xff0c;交换会导致Redis性能急剧下降。所以在生产环境中我们通过配置参数maxmemoey来限制使用的内存大小。当实际使用的内存超过maxmemoey后&…

pytest框架_Python最火的第三方开源测试框架——pytest

一、介绍本篇文章是介绍的是Python 世界中最火的第三方单元测试框架&#xff1a;pytest。它有如下主要特性&#xff1a;assert 断言失败时输出详细信息(再也不用去记忆 self.assert* 名称了)自动发现测试模块和函数模块化夹具用以管理各类测试资源对 unittest 完全兼容&#xf…

jvm jstat_使用jstat的JVM统计信息

jvm jstat过去&#xff0c;我已经写过关于Oracle和/或OpenJDK Java开发工具包&#xff08;JDK&#xff09;附带的几个命令行工具的信息&#xff0c;但是我从来没有专门写过jstat工具 。 Oracle JDK 9文档Early Access指出jstat用于“监视Java虚拟机&#xff08;JVM&#xff09;…

win10录屏工具_win10怎么录屏?这才是最长情陪伴你的录屏工具

win10怎么录屏&#xff1f;现在看视频的用户是越来越多了&#xff0c;一些经验类的视频教程越来越多&#xff0c;不仅能够教我们学习技能&#xff0c;也能给我们看一些会员才能看的视频内容&#xff0c;他们怎么怎么做的呢&#xff1f;当然是电脑录屏了&#xff0c;由于现在的电…

python多行注释符号_涨知识Python 为什么用 # 号作注释符?

- START -关于编程语言中的注释&#xff0c;其重要性基本上已为大家所共识。然而关于注释的规范&#xff0c;这个话题就像我们之前聊过的缩进、终止符和命名方式一样&#xff0c;众口难调。注释符通常可分为两种&#xff0c;即行注释与块注释(inline/block)&#xff0c;它们在不…

Sublime Text如何安装和卸载插件

文章目录如何查找插件如何安装插件通过包控制器安装插件手动安装插件如何卸载插件如何查找插件 建议先通过插件库来搜索你想要的插件&#xff0c;找到你想要的插件之后&#xff0c;你再选择安装方式进行安装&#xff0c;搜索插件请点击以下链接&#xff1a; Package Control中…

@insert 对象_python中列表插入append(), extend(), insert()

1 append()append&#xff1a;只能接收一个参数&#xff0c;并且只能添加在列表的最后。添加数字 In [1]: a [1,2,3] In [2]: a.append(4) In [3]: a Out[3]: [1, 2, 3, 4] 添加字符串 In [6]: a [1,2,3] In [7]: a.append("daniel") In [8]: a Out[8]: [1, 2, 3, …

常用jdk的命令行工具:_jhsdb:JDK 9的新工具

常用jdk的命令行工具:我喜欢在分析性能和基于Java的应用程序的其他问题的早期步骤中使用JDK随附的命令行工具&#xff0c;并在诸如jcmd &#xff0c; jps &#xff0c; jstat &#xff0c; jinfo &#xff0c; jhat和jmap &#xff0c; jrunscript &#xff0c; jstack之类的 工…

佳能2900打印机与win10不兼容_佳能2900打印机和惠普1020哪种好 佳能2900打印机和惠普1020对比【详解】...

现在的人们早已经习惯遇到身边美丽的景色&#xff0c;就用手机进行拍摄下来了&#xff0c;若想长久的留住这一刻的美好&#xff0c;拥有一台 打印机 就是很不错的选择&#xff0c;如今打印机的需求量在不断的增加&#xff0c;市面上的打印机品牌也在不断的增多&#xff0c;我们…

mysql 多表查询 join on_mysql多表查询

在做连表查询的时候&#xff0c;可以在联合的字段上面&#xff0c;分别加上索引字段&#xff0c;这样有加快搜索的速度左右连表查询时条件放在on后面和where后面的执行时机是不一样的例如test1表test2表执行SELECT * FROM test1 t1 LEFT JOIN test2 t2ON t1.not2.no AND t2.nam…

redis key失效的事件_《分享几道高频 Redis 高频面试题,面试不用愁》

1、说说 Redis 都有哪些应用场景&#xff1f;缓存&#xff1a;这应该是 Redis 最主要的功能了&#xff0c;也是大型网站必备机制&#xff0c;合理地使用缓存不仅可以加 快数据的访问速度&#xff0c;而且能够有效地降低后端数据源的压力。共享Session&#xff1a;对于一些依赖 …

解决文件内容的中文乱码_字符集_字符编码_字符编码方案

从第三方下载的java源文件&#xff0c;打开查看里面的中文全部是乱码&#xff0c;无论你使用什么字符编码集都无法正常显示&#xff0c;该文件是用UTF-8编码存档的&#xff0c;使用UTF-8解码也同样是乱码&#xff0c;相信很多人遇到类似的问题&#xff0c;我这里解决过一个经典…

rust为什么显示不了国服_捋捋 Rust 中的 impl Trait 和 dyn Trait

缘起一切都要从年末换工作碰上特殊时期, 在家闲着无聊又读了几首诗, 突然想写一个可以浏览和背诵诗词的 TUI 程序说起. 我选择了 Cursive 这个 Rust TUI 库. 在实现时有这么一个函数, 它会根据参数的不同返回某个组件(如 Button, TextView 等). 在 Cursive 中, 每个组件都实现了…

mysql不支持子查询_MySQL不支持子查询优化一例

一创建表 create table tt1(id int primary key, c1 INT);create table tt2(id int primary key, c2 INT);insert into tt1 value一创建表create table tt1(id int primary key, c1 INT);create table tt2(id int primary key, c2 INT);insert into tt1 values(1,1),(2,2),(3,3…

Mysql索引使用情况_介绍mysql索引失效的情况

mysql视频教程栏目索引失效的情况。索引对于MySQL而言&#xff0c;是非常重要的篇章。索引知识点也巨多&#xff0c;要想掌握透彻&#xff0c;需要逐个知识点一一击破&#xff0c;今天来先来聊聊哪些情况下会导致索引失效。图片总结版相关免费学习推荐&#xff1a;mysql视频教程…

java 类 null_深入理解java中的null“类型”

本文研究的主要是java中的null“类型”的相关实例&#xff0c;具体介绍如下。先给出一道简单的null相关的题目&#xff0c;引发我们对null的探讨,后面会根据官方语言手册对null“类型”进行解读。题目&#xff1a;下面程序能正确运行吗&#xff1f;解析&#xff1a;输出应该为 …

如何彻底禁用Chrome浏览器的缓存功能

禁止Chrome浏览器的缓存功能有几种方式&#xff1a; 使用Shift F5强制刷新缓存。实际使用中我们发现&#xff0c;这种方法对于部分网页的更改并不能做到释放缓存的作用&#xff0c;尤其是无法释放DNS缓存。 使用隐身模式Shift Control N. 这种方法只能在打开的页面上消除之…