IntelliJ 中的 Java JDK 18 打印问号“?”当我尝试打印像“\u1699”这样的unicode时
TLDR:我降级到JDK 17(17.0.2),现在它起作用了...
我在看初学者Java教程,由Kody Simpson在YT上(YouTube.com/watch?v=t9lp9nt9nco),在那个教程中,男孩Kody打印的疯狂符号称为“☯Ωø”,但对我来说只是打印“?” - 问号。
char letter = '\u1699';
System.out.println(letter);
我尝试了堆栈溢出上的几乎所有解决方案,例如:
- 将编码更改为UTF-8的文件,尽管默认情况下是在使用UTF-8。
- 将'-dconsole.encoding = utf-8''和'-dfile.encoding = utf-8'在编辑自定义VM选项中。
- 在控制面板中与区域设置混乱。
这一切都没有起作用。
每个帖子都来自很多年前,例如12年来:
unicode字符在Intellij Idea Console中显示为问号
我最终删除并重新删除了Intellij,因为我以为我以为我弄乱了一些设置并想要重新启动,但是这次我做了一个设置Project SDK旧版本Oracle OpenJDK版本14.0.1,现在以某种方式可以使用并打印了“ᚙ”符号。
然后我意识到问题可能是JDK的最新版本,即第18版,所以我下载了JDK 17.0.2,并且它仍然可以使用并打印出符号'ᚙ',所以很好::)。但是,当我切换回JDK版本18时,它只是打印“?”再次。
这也很奇怪,因为无论您称之为什么,我都可以将past the paste''粘贴复制到书写代码区域(JDK版本18),
char letter = 'ᚙ';
System.out.println(letter);
但是当我按下运行并尝试打印时……它仍然给出问号。
我不知道为什么会发生这种情况,我开始学习编码2天,所以我可能很愚蠢,或者新版本有一个错误,但是我从未通过Google或这里找到解决方案,所以这就是为什么我要使我的有史以来第一个堆栈溢出帖子。
tldr: I downgraded to JDK 17 (17.0.2) and now it works...
I was watching a beginners Java tutorial by Kody Simpson on YT (youtube.com/watch?v=t9LP9Nt9Nco), and in that tutorial the boy Kody prints crazy symbols called Unicode like "☯Ωøᚙ", but for me it just prints "?" - a question mark.
char letter = '\u1699';
System.out.println(letter);
I tried pretty much every solution on Stack Overflow, such as:
- Changing File Encoding to UTF-8, although mine was using UTF-8 by default.
- Putting '-Dconsole.encoding=UTF-8' and '-Dfile.encoding=UTF-8' in the Edit Custom VM options.
- Messing with Region Settings in control panel.
None of it worked.
Every post was also from many years ago, such as this one, which is from 12 years:
unicode characters appear as question marks in IntelliJ IDEA console
I ended up deleting and re-downloading Intellij because I thought I messed up some settings and wanted a restart, but this time I made the Project SDK an older version, Oracle openJDK version 14.0.1, and now somehow it worked and printed the 'ᚙ' symbol.
Then I realized the problem might be the latest version of the JDK which is version 18, so I downloaded JDK 17.0.2, and it BOOM it still works and prints out the symbol 'ᚙ', so thats nice :). But when I switched back to JDK version 18 it just prints "?" again.
Also its strange because I can copy paste the ᚙ symbol into the writing code area whatever you call it, (on JDK version 18)
char letter = 'ᚙ';
System.out.println(letter);
But when I press RUN and try to PRINT ... it STILL GIVES QUESTION MARK.
I have no clue why this happens, I started learning coding 2 days so I'm probably dumb, or the new version has got a bug, but I never found a solution through Google or here, so this is why I'm making my first ever Stack Overflow post.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我可以复制您的问题:如果使用 JDK 17 编译,则在运行代码时打印可以正常工作;如果使用 JDK 18 编译,则在运行代码时打印会失败。Java
18 中实现的更改之一是 JEP 400:默认为 UTF-8。该 JEP 的摘要指出:
这听起来不错,但这一变化的目标之一是(我强调了这一点):
所以我认为你的问题出现是因为你已经确保 Intellij IDEA 中控制台的编码是 UTF-8,但是你用来写入该控制台的
PrintStream
(即System.out< /code>) 不是。
的 Javadoc >PrintStream
声明(添加了我的强调):由于您的
PrintStream
是System.out
,因此您没有指定任何“编码或字符集”,因此使用“默认值” charset”,这可能不是 UTF-8。因此,要让您的代码在 Java 18 上运行,您只需确保您的PrintStream
使用 UTF-8 进行编码。下面是一些示例代码来显示问题和解决方案:这是运行该代码时控制台中的输出:
注意:
PrintStream
有一个 Java 18 中名为charset()
其中“返回此 PrintStream 实例中使用的字符集”。上面的代码调用 charset(),并显示对于我的机器,我的“默认字符集”是 windows-1252,而不是 UTF-8。更新:为了解决 Mostafa Zeinali 在下面的评论中提出的问题,
System.out
使用的PrintStream
可以重定向到 UTF-8PrintStream 通过调用 System.setOut()
。以下是示例代码:这是该代码在我的 Windows 10 计算机上的输出:
请注意,
System.out
是一个final
变量,因此您不能直接分配新变量PrintStream
到它。此代码无法编译,并出现错误“无法为最终变量'out'赋值”:I can replicate your problem: printing works correctly when running your code if compiled with JDK 17, and fails when running your code if compiled with JDK 18.
One of the changes implemented in Java 18 was JEP 400: UTF-8 by Default. The summary for that JEP stated:
That sounds good, except one of the goals of that change was (with my emphasis added):
So I think your problem arose because you had ensured that the console's encoding in Intellij IDEA was UTF-8, but the
PrintStream
that you were using to write to that console (i.e.System.out
) was not.The Javadoc for
PrintStream
states (with my emphasis added):Since your
PrintStream
wasSystem.out
, you had not specified any "encoding or charset", and were therefore using the "default charset", which was presumably not UTF-8. So to get your code to work on Java 18, you just need to ensure that yourPrintStream
is encoding with UTF-8. Here's some sample code to show the problem and the solution:This is the output in the console when running that code:
Notes:
PrintStream
has a new method in Java 18 namedcharset()
which "returns the charset used in this PrintStream instance". The code above calls charset(), and shows that for my machine my "default charset" is windows-1252, not UTF-8.UPDATE: To address the issue raised in the comments below by Mostafa Zeinali, the
PrintStream
used bySystem.out
can be redirected to a UTF-8PrintStream
by callingSystem.setOut()
. Here's sample code:This is the output from that code on my Windows 10 machine:
Note that
System.out
is afinal
variable, so you can't directly assign a newPrintStream
to it. This code fails to compile with the error "Cannot assign a value to final variable 'out'":TLDR:在 Java 18 上使用它:
来自 JEP 400:
正如您所看到的,这两个系统属性“仍未指定且不受支持”。但他们解决了我的问题。因此,请自行承担使用它们的风险,并且不要在生产环境中使用它们。顺便说一句,我正在 Windows 10 上运行 Eclipse。
我认为必须有一个好方法来设置JVM在运行时的默认字符集,并且传递-Dfile.encoding =“UTF-8”并不能做到这一点是愚蠢的。正如您在 JEP 400 中所读到的:
而这正是它“不”做的事情。传递 Dfile.encoding="UTF-8" 不会“不”保留现有命令行的行为!我认为这表明 Java 18 对 JEP 400 的实现没有做它实际应该做的事情,这首先是问题的根源。
TLDR: Use this on Java 18:
From JEP 400:
As you can see, those two system properties "remain unspecified and unsupported". But they solved my problem. Therefore, please use them at your own risk, and DO NOT use them in production env. I'm running Eclipse on Windows 10 btw.
I think there must be a good way to set the default charset of JVM upon running, and it is stupid that passing -Dfile.encoding="UTF-8" does not do that. As you can read in JEP 400:
And this is exactly what it is "NOT" doing. Passing Dfile.encoding="UTF-8" does "not" preserve the behavior of existing command lines! I think this shows that Java 18's implementation of JEP 400 is not doing what it should actually be doing, which is the root of your problem in the first place.
将 IntelliJ IDEA 更新到版本 2022.2.1+。非常相似的问题被归类为错误。您可以找到更多详细信息 此处。
Update IntelliJ IDEA to version 2022.2.1+. Very similar problem was classified as a bug. You can find more details here.
也遇到过这样的烦恼。将设置(文件 > 设置... > 编辑器 > 常规 > 控制台)更改为 UTF-32 有助于解决此问题。
Had such trouble as well. Changing setting (File > Settings... > Editor > General > Console) into UTF-32 helped to solve this issue.