我真的不明白为什么non-sealedJEP 360/Java 15 中有一个关键字。对我来说,密封类的扩展应该只是 final 或密封类本身。
提供“非密封”关键字将邀请开发人员进行黑客攻击。为什么我们允许将密封类扩展为非密封类?
因为我使用的是 Java 14 和 15 预览功能。试图在java中找到字符串插值。
我找到的最接近的答案是
String.format("u1=%s;u2=%s;u3=%s;u4=%s;", u1, u2, u3, u4)
由于我从很多参考资料中得到的答案是 4,5 年前提出的旧答案。java 11,12,13,14,15 中的字符串插值是否有任何更新,相当于 C#
string name = "Horace";
int age = 34;
Console.WriteLine($"Your name is {name} and your age {age}");
Run Code Online (Sandbox Code Playgroud) 假设我有这个简单的方法:
static final Integer me = Integer.parseInt("2");
static int go() {
return me * 2;
}
Run Code Online (Sandbox Code Playgroud)
对于 javac,me不是常量(根据 JLS 规则),但对于 JIT 很可能是。
我试图用以下方法测试:
public class StaticFinal {
public static void main(String[] args) {
int hash = 0;
for(int i=0;i<1000_000;++i){
hash = hash ^ go();
}
System.out.println(hash);
}
static final Integer me = Integer.parseInt("2");
static int go() {
return me * 2;
}
}
Run Code Online (Sandbox Code Playgroud)
并运行它:
java -XX:+UnlockDiagnosticVMOptions
-XX:-TieredCompilation
"-XX:CompileCommand=print,StaticFinal.go"
-XX:PrintAssemblyOptions=intel
StaticFinal.java
Run Code Online (Sandbox Code Playgroud)
我不知道汇编很好,但这很明显:
mov eax,0x4
Run Code Online (Sandbox Code Playgroud)
的结果go立即为4,即:JIT“信任” …
我有一个现有的非模块化 Spring Boot 应用程序,它使用 Nashorn。该应用程序在 Java 14 上运行良好。
添加可用于 Java 15 的新 Nashorn 的 Maven 坐标后,应用程序在启动脚本引擎时失败。
public static void main(String[] args) throws ScriptException {
ScriptEngineManager factory = new ScriptEngineManager();
ScriptEngine engine = factory.getEngineByName("nashorn");
engine.eval("print('Hello, World!');");
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "javax.script.ScriptEngine.eval(String)" because "engine" is null
at xxxxx.yyyy.service.JavaScriptServiceImpl.main(JavaScriptServiceImpl.java:52)
Run Code Online (Sandbox Code Playgroud)
是否需要将整个项目模块化才能使用 Nashorn?
我有一个关于映射Instant到 PostgreSQL 的最佳实践问题TIMESTAMP。
我们已将应用程序更新到 Java 15,系统时钟的新增强功能为纳秒精度 ( https://bugs.openjdk.java.net/browse/JDK-8242504 ) 与 Postgres 中的 TIMESTAMP 限制不兼容。时间根据底层操作系统的不同而不同,Mac (Big Sur) 中的 Instant 不提供以纳秒为单位的时间,但 Linux 中提供。
我们在代码库中使用即时类型。我们的测试正在比较内存中的 Instant 类型的对象与获取的对象,因此它们会失败,具体取决于它们运行的操作系统。
在Linux中,内存中的Instant对象的精度为纳秒,而Postgres存储的Instant(TIMESTAMP)的精度为微秒。断言失败:
java.lang.AssertionError: expected [2021-01-04T19:32:23.726475249Z] but found [2021-01-04T19:32:23.726475Z]
Run Code Online (Sandbox Code Playgroud)
在 Mac 中,Instant 对象的精度为微秒,与 Postgres 的时间戳精度充分一致,因此测试会像迄今为止所做的那样通过。
我们希望避免截断 Instant 或向 PG 添加插件来支持纳秒。
其他人如何以稳健、全面的方式处理这个问题?
我正在尝试在运行时编译和加载动态生成的 Java 代码。由于 ClassLoader::defineClass 和 Unsafe::defineAnonymousClass 在这种情况下都有严重的缺点,因此我尝试通过Lookup::defineHiddenClass使用隐藏类。这对于我尝试加载的所有类都适用,但调用 lambda 表达式或包含匿名类的类除外。
调用 lambda 表达式会引发以下异常:
Exception in thread "main" java.lang.NoClassDefFoundError: tests/HiddenClassLambdaTest$LambdaRunner/0x0000000800c04400
at tests.HiddenClassLambdaTest.main(HiddenClassLambdaTest.java:22)
Caused by: java.lang.ClassNotFoundException: tests.HiddenClassLambdaTest$LambdaRunner.0x0000000800c04400
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:636)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:182)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:519)
... 1 more
Run Code Online (Sandbox Code Playgroud)
执行实例化匿名类的代码会引发以下错误:
Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400.run()V @5: invokespecial
Reason:
Type 'tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400' (current frame, stack[2]) is not assignable to 'tests/HiddenClassLambdaTest$LambdaRunner'
Current Frame:
bci: @5
flags: { }
locals: { 'tests/HiddenClassLambdaTest$LambdaRunner+0x0000000800c00400' }
stack: { uninitialized 0, uninitialized …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 Eclipse 2020-09 下运行新的 Java 15 功能。
我已经安装了 OpenJDK 15 并将其设置在“已安装的 JRE”下:
尽管如此,我无法将此版本设置为编译器版本(仅到版本 14):
我究竟做错了什么?
密封类和密封接口是Java 15中的一个预览功能,在 Java 16 中有第二个预览,现在建议在 Java 17 中交付。
他们提供了典型的例子一样Shape- > Circle,Rectangle等等。
我理解密封类:switch提供的语句示例对我来说很有意义。但是,密封接口对我来说是个谜。任何实现接口的类都被迫为它们提供定义。接口不会损害实现的完整性,因为接口本身是无状态的。我是否想将实现限制为几个选定的类并不重要。
你能告诉我 Java 15+ 中密封接口的正确用例吗?
我以前使用过这个人为的代码
record Foo(int bar[]) {}
Run Code Online (Sandbox Code Playgroud)
这是利用 C 风格的数组符号。它在 Java 15 中编译得很好。
现在,突然之间,随着Java 16中记录的正式发布,它不再编译了。这是jshell的输出:
Run Code Online (Sandbox Code Playgroud)record Foo(int bar[]) {}
为什么它在 Java 15 中编译,这是一个错误吗?出于好奇,为什么它在记录中不受支持,而在 Java 的其他任何地方都受支持?
我正在使用javac来自Adoptium(基于 OpenJDK)。
在我的 Java 应用程序中,一个重要的小功能是能够根据音频文件的元数据(例如专辑/艺术家 -title)重命名音频文件,并且使用Javascript指定掩码,这使得重命名功能非常灵活和强大。
我知道 Javascript 已被弃用,但现在看来它实际上将从 Java 15 中删除。这种功能的丢失对我来说可能是一个主要问题,所以我问,即使它被正式删除,我是否可以继续在 Java 15 应用程序中使用 Javascript,即它是否可以作为 opensrc 插件使用,我可以在我自己的风险。开发在 Ecmascript 5.1 停止的事实对我来说不是一个主要问题。
有人提到使用GraalVM,但没有解释如何执行此操作,我认为这不适合我的场景,特别是我的应用程序可用于某些 32 位Arm环境,而 GraalVM 不可用于 32 位。
我已经从 Java 11 转移到 Java 14 以解决其他一些问题,所以我不能真正回到 Java 11,而且由于 Java 14 不是LTS版本,我不能真正坚持使用 Java 14 很长一段时间。
这是我的大部分 Javascript 代码
try
{
mask = includeUserDefinedFunctions(mask);
ScriptEngine engine = manager.getEngineByName("JavaScript");
for(SongFieldName next:SongFieldName.values())
{
if(next.getScriptVar()!=null && next.getSongFieldKey()!=null)
{
engine.put(next.getScriptVar(), cleanValue(song.getFieldValueSpaceSeparatedOrEmptyString(next.getSongFieldKey()), song));
}
}
String result = (String)engine.eval(mask);
return result;
} …Run Code Online (Sandbox Code Playgroud) java ×10
java-15 ×10
nashorn ×2
sealed-class ×2
arrays ×1
classloader ×1
eclipse ×1
interface ×1
java-14 ×1
java-16 ×1
java-record ×1
java-time ×1
jep ×1
jit ×1
jvm ×1
postgresql ×1
string ×1