我最近尝试了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代码段的环境。
答案 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的功能,但它正常工作。
Java 8编译器将告诉您。假设您设置了平台依赖性,IDE也将如此。
您也许可以使用-C
选项来获取jshell
来根据Java 8 API编译代码。
1-如果您努力解决jshell类中的这些预期的依赖关系以及其他Java 9+依赖关系,那么您将成功将其反向移植到Java8。成名和命运在等待着您: -)