tldr:我降级到 JDK 17 (17.0.2),现在它可以工作了......
\n我在 YT 上观看 Kody Simpson 的 Java 初学者教程 (youtube.com/watch?v=t9LP9Nt9Nco),在该教程中,男孩 Kody 打印了名为 Unicode 的疯狂符号,例如“\xe2\x98\xaf\xce\xa9\xc3” \xb8\xe1\x9a\x99",但对我来说它只是打印“?” - 一个问号。
\nchar letter = \'\\u1699\';\nSystem.out.println(letter);\nRun Code Online (Sandbox Code Playgroud)\n我尝试了 Stack Overflow 上的几乎所有解决方案,例如:
\n这些都不起作用。
\n每一个帖子都是很多年前的,比如这个,是12年前的:
\nunicode 字符在 IntelliJ IDEA 控制台中显示为问号
\n我最终删除并重新下载了 Intellij,因为我认为我弄乱了一些设置并想要重新启动,但这次我将 Project SDK 设置为旧版本,Oracle openJDK 版本 14.0.1,现在它以某种方式工作并打印了 \ '\xe1\x9a\x99\' 符号。
\n然后我意识到问题可能是 JDK 的最新版本,即版本 18,所以我下载了 JDK 17.0.2,它仍然可以工作并打印出符号 \'\xe1\x9a\x99\',所以那就是好的 :)。但是当我切换回 JDK 版本 18 时,它只打印“?” 再次。
\n这也很奇怪,因为我可以将 \xe1\x9a\x99 …
以下小型 Java 程序和jpackage命令创建一个应用程序映像,该映像在 Windows 10 上启动时会启动多个 exe。在 JDK 17 之前不会发生这种情况。使用 JDK 16 jpackage 的相同代码和命令会导致“任务管理器详细信息”选项卡中仅运行一个 Main.exe 实例。JDK 18 和 19 中似乎仍然会出现此问题。
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JDialog dialog = new JDialog();
dialog.setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
jpackage --type app-image --input jpackage_test_jar --dest install/tmp --main-jar jpackage_test.jar --main-class Main
在 JDK 15、16、17、18 和 19 上测试了相同的代码和 jpackage 命令。在 JDK 17、18 和 19 中的 Windows 10 上启动了多个 exe,但在 15 或 16 中则不然。JDK 15 来自 AdoptOpenJDK,其余的是来自 Eclipse …
ServiceLoader.java 文档指出:
强烈建议应用程序模块不需要包含服务提供者的模块。
为什么强烈建议这样做,如果不遵循建议会发生什么?
上下文:这间接意味着定义服务的模块不应该导出该服务的提供者。我认为在同一模块中提供服务的默认实现会很方便。
我想使用巴拿马项目中的外部函数接口来访问 Java19 中的 C 库。C 接口非常简单:
typedef struct {
int len;
char name[100];
} ent;
ent* foo();
Run Code Online (Sandbox Code Playgroud)
调用时,函数 foo 返回指向 的指针struct ent,其中len指示字符串的大小name。
对应的Java端是:
private static final MemoryLayout ENT_LAYOUT = MemoryLayout.structLayout(
JAVA_INT.withName("len"),
MemoryLayout.sequenceLayout(100, ValueLayout.JAVA_BYTE).withName("name")
);
Run Code Online (Sandbox Code Playgroud)
为了方便访问,我想使用VarHandle:
private static final VarHandle VH_ENT_LEN = ENT_LAYOUT.varHandle(groupElement("len"));
Run Code Online (Sandbox Code Playgroud)
以及后来
int len = (int)VH_ENT_LEN.get(segment);
String name = segment.asSlice(ENT_LAYOUT.byteOffset(groupElement("name")), len).getUtf8String(0);
Run Code Online (Sandbox Code Playgroud)
这仍然有点混乱。
我天真的期望解决方案应该是这样的:
private static final VarHandle VH_ENT_NAME = ENT_LAYOUT.varHandle(groupElement("name"), sequenceElement());
byte[] nameRaw = (byte[])VH_ENT_NAME.get(segment);
Run Code Online (Sandbox Code Playgroud)
但是我得到:
java.lang.RuntimeException: java.lang.invoke.WrongMethodTypeException:
cannot convert MethodHandle(VarHandle,MemorySegment,long)byte …Run Code Online (Sandbox Code Playgroud)