【发布时间】:2021-07-04 03:36:54
【问题描述】:
根据From compilation to runtime, how does Java String encoding really work,Java 类文件中的字符串与使用的代码页无关。但是我在GBK(中国使用的ANSI编码)机器上的Java程序中发现了以下问题。 假设以下字符:
字符串
ANSIStringAsUTF 是 AString 用 ANSI 编码并用 UTF-8 解码时的样子。
UTFStringAsANSI 是 AString 使用 UTF-8 编码并使用 ANSI 解码时的样子。
所以当我用 ANSI 在 notepad++ 中输入 AString 时,保存文件并用 ANSI 打开文件,它看起来是正确的。如果我用 UTF-8 打开文件,它会显示 ANSIStringAsUTF。 当我使用 UTF-8 在记事本 ++ 中输入 AString 时,保存文件并使用 UTF-8 打开文件,它看起来是正确的。如果我用 ANSI 打开文件,它会显示 UTFStringAsANSI。很好!
public class Main {
public static void main(String[] args) {
System.out.println(*AString*);
}
}
我在 Windows 控制台中使用 ANSI 代码页 936 编译上述以 UTF-8 编码的 java 文件,然后运行它。它看起来和预期的一样。 我使用 chcp 命令将代码页更改为 65001(UTF-8) 并运行它,它显示 ANSIStringAsUTF。
我在带有 UTF-8 代码页的 Windows 控制台中编译上面以 UTF-8 编码的 java 文件,然后运行它。它看起来和预期的一样。 我使用 chcp 命令将代码页更改为 936 并运行它,它显示 UTFStringAsANSI。
行为与使用 notepad++ 编辑文件相同,即使用的代码页决定 Java 中字符串的编码和解码。谁能告诉我为什么?抱歉这个冗长的问题。
【问题讨论】:
-
“使用的代码页决定了 Java 中字符串的编码和解码”——我认为你没有证明这一点。您已经证明它会影响字符串在控制台上的显示方式。我建议您将“内存中存在的字符串”和“调用 System.out.println 的结果”这两个想法分开。理想情况下,更改您的代码以转储 UTF-16 代码单元(作为整数)以及作为文本的字符串。这样您就可以轻松区分。
-
Java 字符串独立于编码。但源代码不是。而控制台不是。而读写文本文件则不然。对于所有这些,需要理解和控制所涉及的编码。许多人遇到编码问题并添加 print 语句,从而引入更多编码问题而不是解决问题。您想提高对编码的理解,还是有特定的问题需要解决?
-
感谢 cmets。我确实了解字符串编码和源代码等之间的区别。但是 1. 程序以某种方式正确打印的事实表明 AString 在两种情况下都在编译期间正确解码。 2. 程序以某种方式打印不正确的事实表明 Java 没有根据使用的代码页正确编码输出字符串。 3. 两种情况不同,说明使用的代码页对编译的类有影响。 4. 更糟糕的是,结果各不相同,有时我在使用 UTF-8 打开时在两个编译类中都发现了 UTFStringAsANSI。
标签: java encoding utf-8 decoding ansi