我试图理解jshell并摸索导入外部库.截至目前,我无法看到任何建议/解决方案.
有人可以告诉我,如果已经弄清楚这一点.
我将安装Android Studio 3以开发Android应用程序.
我想知道是否可以使用Java 9进行Android开发?如果是这样,它是否支持所有Java 9功能?
Java 9最大的功能之一将是Project Jigsaw定义的模块系统.在阅读Project Jigsaw:在 JavaOne 2015 的Hood下阅读幻灯片时,我注意到以下源代码:
// src/java.sql/module-info.java
module java.sql {
exports java.sql;
exports javax.sql;
exports javax.transaction.xa;
}
Run Code Online (Sandbox Code Playgroud)
这里有趣的是文件结尾.java并且似乎使用了两个新的关键字:module,和exports.Java 9中将引入哪些其他关键字?如何处理向后兼容性(即命名的函数或变量module)?
我正在尝试在Java 9上运行我的Spring Boot应用程序,并且我遇到了JAXB问题,该问题在指南中有所描述,但对我来说并不适用.我添加了对JAXB api的依赖,应用程序开始工作.如果您收到以下异常,则由于缺少使用Java版本> = 9的JAXB缺失实现:
javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:177) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:364) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:508) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:465) ~[jaxb-api-2.3.0.jar:2.3.0]
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:366) ~[jaxb-api-2.3.0.jar:2.3.0]
at com.sun.jersey.server.impl.wadl.WadlApplicationContextImpl.<init>(WadlApplicationContextImpl.java:107) ~[jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.wadl.WadlFactory.init(WadlFactory.java:100) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.RootResourceUriRules.initWadl(RootResourceUriRules.java:169) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.RootResourceUriRules.<init>(RootResourceUriRules.java:106) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.WebApplicationImpl._initiate(WebApplicationImpl.java:1359) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.WebApplicationImpl.access$700(WebApplicationImpl.java:180) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.WebApplicationImpl$13.f(WebApplicationImpl.java:799) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.WebApplicationImpl$13.f(WebApplicationImpl.java:795) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193) [jersey-core-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:795) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:790) [jersey-server-1.19.1.jar:1.19.1]
at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:509) [jersey-servlet-1.19.1.jar:1.19.1]
at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:339) [jersey-servlet-1.19.1.jar:1.19.1]
at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:605) [jersey-servlet-1.19.1.jar:1.19.1]
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:207) [jersey-servlet-1.19.1.jar:1.19.1]
at …Run Code Online (Sandbox Code Playgroud) 我在我的项目中使用了龙目岛,但我的同事不同意使用它,他的理由是(来自lombok文件的争议)
这两个项目Lombok都利用非公共API来完成他们的巫术.这意味着使用后续IDE或JDK版本可能会破坏Project Lombok的风险.
但这是一篇2010年写的非常古老的文档,也许现在已经解决了这个问题,所以我想知道Lombok是否支持Java 9并且它仍然使用非公共API:s?
"作为添加对Lambda表达式的支持的努力的一部分,简单地考虑将接口中的私有方法支持包含在Java SE 8中,但是为了更好地关注Java SE 8的更高优先级任务而被撤回.现在提议支持私有接口方法,从而使接口的非抽象方法能够在它们之间共享代码."
所以说http://openjdk.java.net/jeps/213的规范, 并在错误报告https://bugs.openjdk.java.net/browse/JDK-8071453中说.
但是,即使有上面给出的简短解释,我也无法想到任何必要的用例.我可以问一个例子,"私有接口方法"在代码方面是否有用?
编辑:所以答案是,由于Java 8中的接口添加了默认实现,可能存在默认实现使用相同代码库的情况.
例如,
public interface MyInterface {
default void initializeMyClass(MyClass myClass, Params params) {
//do magical things in 100 lines of code to initialize myClass for example
}
default MyClass createMyClass(Params params) {
MyClass myClass = new MyClass();
initializeMyClass(myClass, params);
return myClass;
}
default MyClass createMyClass() {
MyClass myClass = new MyClass();
initializeMyClass(myClass, null);
return myClass;
}
}
Run Code Online (Sandbox Code Playgroud)
愚蠢的例子,我知道.但是,让我们说我们想要initializeMyClass(MyClass, Params)在两种方法中使用.但是,如果我们这样做(默认方法),那么initializeMyClass(MyClass, Params)将成为公共接口的一部分!为了防止这种情况发生,我们只能将整个代码保留initializeMyClass(MyClass, Params) …
Java 9有三种方法可以将编译后的代码打包到文件中:
JIMAGE针对速度和空间进行了优化,并在运行时由JVM使用,因此有理由引入JIMAGE.JIMAGE文件不应发布到maven repos或在编译或链接时使用.
文档声称JMOD可以存储本机代码和JAR文件无法存储的其他内容,开发人员可以制作和分发自己的JMOD文件.JDK附带jmods/包含JDK 所有模块的目录,供用户依赖.
问题:
以下简单类(repo重现它):
import static org.hamcrest.*;
import static org.junit.Assert.assertThat;
import java.util.*;
import org.junit.Test;
public class TestGenerics {
@Test
public void thisShouldCompile() {
List<String> myList = Arrays.asList("a", "b", "c");
assertThat("List doesn't contain unexpected elements", myList, not(anyOf(hasItem("d"), hasItem("e"), hasItem("f"))));
}
}
Run Code Online (Sandbox Code Playgroud)
行为取决于JDK版本:
出现以下错误:
[ERROR] /tmp/jdk-issue-generics/src/test/java/org/alostale/issues/generics/TestGenerics.java:[17,17] no suitable method found for assertThat(java.lang.String,java.util.List<java.lang.String>,org.hamcrest.Matcher<java.lang.Iterable<? super java.lang.Object>>)
method org.junit.Assert.<T>assertThat(java.lang.String,T,org.hamcrest.Matcher<? super T>) is not applicable
(inference variable T has incompatible bounds
upper bounds: java.lang.String,java.lang.Object
lower bounds: capture#1 of ? super T?,capture#2 …Run Code Online (Sandbox Code Playgroud) 如何指示jshell在脚本结尾处终止,类似于其他语言的解释器,例如python3或node?
遵循命令
./jshell -q /tmp/shell.java
Run Code Online (Sandbox Code Playgroud)
用脚本 /tmp/shell.java
System.out.println("Hello world");
Run Code Online (Sandbox Code Playgroud)
版画
Hello world
jshell>
Run Code Online (Sandbox Code Playgroud)
并等待进一步的命令.我希望它立即停止在文件的末尾.
我正在寻找比System.exit(0);脚本末尾更优雅的东西.
假设我有一个使用Maven 3和junit的Java项目.有src/main/java和src/test/java目录分别包含主要来源和测试来源(一切都是标准的).
现在我想将项目迁移到Java 9. src/main/java内容代表Java 9模块; 有com/acme/project/module-info.java看大约是这样的:
module com.acme.project {
require module1;
require module2;
...
}
Run Code Online (Sandbox Code Playgroud)
如果测试代码需要module-info.java自己怎么办?例如,添加对某些模块的依赖性,该模块仅用于测试,而不是生产代码.在这种情况下,我必须把module-info.java以src/test/java/com/acme/project/给模块不同的名称.这样Maven似乎将主要源和测试源视为不同的模块,因此我必须将包从主模块导出到测试模块,并且需要测试模块中的包,如下所示:
主模块(in src/main/java/com/acme/project):
module prod.module {
exports com.acme.project to test.module;
}
Run Code Online (Sandbox Code Playgroud)
测试模块(in src/test/java/com/acme/project):
module test.module {
requires junit;
requires prod.module;
}
Run Code Online (Sandbox Code Playgroud)
这产生了
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project test-java9-modules-junit: Compilation failure: Compilation failure:
[ERROR] /home/rpuch/git/my/test-java9-modules-junit/src/test/java/com/acme/project/GreeterTest.java:[1,1] package exists in another module: prod.module
Run Code Online (Sandbox Code Playgroud)
因为一个包在两个模块中定义.所以现在我必须在主模块和测试模块中有不同的项目,这是不方便的.
我觉得我走错了道路,一切都开始看起来非常难看.如何module-info.java在测试代码中拥有自己的代码,或者如何在没有测试代码的情况下实现相同的效果(require …