Java Unicode Confusion
Java Unicode Confusion
大家好,我刚开始尝试学习Java,遇到了一些令人困惑的问题!
我正在打字书中的一个例子,用来演示char数据类型。
代码如下:
public class CharDemo
{
public static void main(String [] args)
{
char a = 'A';
char b = (char) (a + 1);
System.out.println(a + b);
System.out.println("a + b is " + a + b);
int x = 75;
char y = (char) x;
char half = '\u00AB';
System.out.println("y is " + y + " and half is " + half);
}
}
让我感到困惑的是语句char half = '\u00AB'。书中指出,\u00AB是表示符号'1/2'的代码。正如描述的那样,当我从cmd编译和运行程序时,在这一行产生的符号实际上是'1/2'。
所以一切似乎都按照应该的方式运行。我决定尝试一些不同的Unicode,并搜索了多个Unicode表,发现它们都与上述结果不一致。
我在每一个表中都看到,/u00AB的代码不是表示'1/2',而是表示这个:
http://www.fileformat.info/info/unic...r/ab/index.htm
那么Java使用的是哪个字符集?我以为UNicode应该是唯一的。我已经搜索了几个小时,但没有找到任何字符集说明/u00AB等于1/2,但这正是我的Java编译器解释的。
我肯定是漏了一些显而易见的东西!谢谢帮助!
Java Unicode混淆问题的出现原因是由于不同的字符编码系统之间的差异。在Windows终端中,默认使用的是Codepage 437字符编码系统,而Java中使用的是Unicode字符编码系统。
在Codepage 437中,十六进制值0xAB表示字符"½",而在Unicode中,该值表示字符"«"。因此,在Java程序中,char值代表的是"«"字符。如果在GUI中渲染这个char值,或者在一个正常的操作系统上运行它,你将看到该字符。如果你想在Windows终端中看到正确的输出,可以通过在CMD中更改字体设置来实现(点击左上角图标,选择Properties,然后切换到Font选项卡)。例如,使用Lucida Console字体,可以这样操作:
C:\Users\Documents>java CharDemo
131
a + b is AB
y is K and half is ½
C:\Users\Documents>chcp 1252
Active code page: 1252
C:\Users\Documents>java CharDemo
131
a + b is AB
y is K and half is «
C:\Users\Documents>chcp 437
Active code page: 437
该问题的解决方法是在Windows终端中更改字体设置,以便正确显示Unicode字符。此外,建议寻找一本讲解Java基础和基本概念的新书。
Java Unicode混淆问题的出现原因是在使用System.out PrintStream时,可能会遇到默认字符编码不是UTF-8或Latin-1的平台。这可能是一些Windows字符集,这也可以解释为什么\u00ab会显示为1/2而不是其他字符。
解决这个问题的方法是,可以使用PrintWriter代替PrintStream来避免Unicode混淆。PrintWriter有一个构造函数,可以指定字符编码,以确保正确地打印Unicode字符。
下面是一个示例代码,演示如何使用PrintWriter来解决Java Unicode混淆问题:
import java.io.*; public class UnicodeConfusion { public static void main(String[] args) throws UnsupportedEncodingException { String unicodeString = "\u00ab"; System.setOut(new PrintWriter(new OutputStreamWriter(System.out, "UTF-8"), true)); System.out.println(unicodeString); } }
在这个示例中,我们将System.out设置为PrintWriter,并在构造PrintWriter时指定了UTF-8字符编码。这样,当我们打印Unicode字符串时,它将以正确的形式显示出来。
总之,Java Unicode混淆问题的原因是使用System.out PrintStream时可能遇到默认字符编码不正确的平台。通过使用PrintWriter并指定正确的字符编码,我们可以解决这个问题。
Java中的Unicode混淆问题主要是由于Windows平台上控制台编码不匹配引起的。
Java运行时期望系统控制台使用的编码与系统默认编码相同。然而,Windows使用两种不同的编码:ANSI代码页(系统默认编码)和OEM代码页(控制台编码)。
因此,当您尝试将Unicode字符U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
写入控制台时,Java运行时期望控制台编码为ANSI编码(在您的情况下为Windows-1252),其中该Unicode字符表示为0xAB
。然而,实际的控制台编码是OEM编码(在您的情况下为CP437),其中0xAB
表示½
。
因此,使用System.out.println()
将数据打印到Windows控制台会产生错误的结果。
为了获得正确的结果,您可以改用System.console().writer().println()
。
谢谢,这很有道理,但是你提到将数据打印到Windows控制台会产生错误的结果。这个例子来自一本Java书,作者知道AB将是一半。这只是他没有解释清楚的写作问题吗?
:那就是写作问题了。也许作者很少使用非US-ASCII字符,因此对这个问题不熟悉。
+1.这真是愚蠢。Java和Windows都使用UTF-16LE编码的本地Unicode字符串。然而,它们仍然无法在不通过字节的字符处理编码解码循环的情况下进行通信。