我想在JDK 8

时间:2018-11-26 06:04:13

标签: java jshell

我最近尝试了JDK 11 jshell,并且喜欢能够交互式地测试核心Java中记录的内容。尽管我的公司仍然与Java 8发行版保持联系。所以我想我会尝试看看是否可以使用jshell与JDK 8一起使用。

编辑尝试解释似乎不清楚的地方:我想使用JShell,但将Java 8 API用于交互模式,脚本,完成,JavaDoc等。

我对jshell所做的工作的心理模型是:它是使用提供的JDK构建的,因此可以在为其构建的JRE上运行,但我认为它已加载了JavaDoc,从一个jar的JDK集合中完成,并针对另一个JVM实例运行交互式脚本,而该JVM不一定与运行该版本的版本相同。因此,我认为我可以使用JAVA_HOME环境变量来控制第二部分。

在Mac上,我最简单的尝试是:

JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/ \
/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/bin/jshell

但这对我来说并不明显(我将换行):

jshell> System.getProperties()
$3 ==> {gopherProxySet=false, awt.toolkit=sun.lwawt.macosx.LWCToolkit,
java.specification.version=11, sun.cpu.isalist=, sun.jnu.encoding=UTF-8,
java.class.path=., java.vm.vendor=Oracle Corporation, sun.arch.data.model=64, 
java.vendor.url=http://java.oracle.com/, user.timezone=, os.name=Mac OS X, 
java.vm.specification.version=11, sun.java.launcher=SUN_STANDARD, user.country=US,
sun.boot.library.path=/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/lib,
sun.java.command=jdk.jshell.execution.RemoteExecutionControl 55110, 
jdk.debug=release, sun.cpu.endian=little, user.home=/Users/lamblin,
user.language=en, java.specification.vendor=Oracle Corporation, 
... 
patch.level=unknown,
java.library.path=/Users/lamblin/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:., 
java.vendor=Oracle Corporation, java.vm.info=mixed mode,
java.vm.version=11.0.1+13-LTS, sun.io.unicode.encoding=UnicodeBig,
java.class.version=55.0}

jshell> System.getenv("JAVA_HOME")
$4 ==> "/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/"

jshell> exit

为什么? Stream.ofNullable(T)是Java 9的新功能,虽然我想告诉我它不是Java 8的功能,但它正常工作。

jshell> Stream.ofNullable(null).iterator().hasNext()
$3 ==> false

jshell> Stream.ofNullable("hi").iterator().hasNext()
$4 ==> true

jshell> Stream.ofNullable(
Signatures:
Stream<T> Stream<T>.<T>ofNullable(T t)

<press tab again to see documentation>

jshell> Stream.ofNullable(
Stream<T> Stream<T>.<T>ofNullable(T t)
Returns a sequential Stream containing a single element, if non-null, otherwise returns an
empty Stream .

Type Parameters:
T - the type of stream elements

Parameters:
t - the single element

Returns:
a stream with a single element if the specified element is non-null, otherwise an empty stream

<press tab again to see all possible completions; total possible completions: 544>

jshell> Stream.ofNullable(

jshell可能无法满足我的需求。 我开始想这是当我在JDK 8上的NetBeans中使用jshell观看视频时出现的。该视频可能是在误解实际完成的事情。

我确实发现更改类路径不是我所追求的,因为那样会阻止jshell加载所需的类。

所以不要:/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/bin/jshell --class-path /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/*

可以正常启动jshell,然后使用/env -class-path /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/rt.jar将JRE 8罐之一添加到类路径中。可以使用jre/lib中的所有jar来完成此操作,但不会卸载或替换已加载的内容,因此最终不会给您提供仅限于运行Java 8代码段的环境。

1 个答案:

答案 0 :(得分:3)

在Java 8中未使用jshell

JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/ \
/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/bin/jshell

为什么?因为JDK工具实际上并不使用$ JAVA_HOME来决定使用哪个JVM。而是由可执行文件(或包装脚本)根据其文件位置做出决定。

但是您可以通过运行jshell -version来确认。 (注意:只有一个- !!)


如果下载OpenJDK源代码,则可以看到jshell主要用Java实现。它有一个主要方法。因此,您可能可以使用Java 8编译器来编译jshell类。但这很可能失败 1 ,因为jshell知道模块,这意味着它依赖于Java 9中与模块相关的API更改。

但是...为什么要打扰?

  

为什么? Stream.ofNullable(T)是Java 9的新功能,虽然我想告诉我它不是Java 8的功能,但它正常工作。

  1. Java 8编译器将告诉您。假设您设置了平台依赖性,IDE也将如此。

  2. 您也许可以使用-C选项来获取jshell来根据Java 8 API编译代码。


1-如果您努力解决jshell类中的这些预期的依赖关系以及其他Java 9+依赖关系,那么您将成功将其反向移植到Java8。成名和命运在等待着您: -)