Java Unicode混淆

Nic*_*ick 6 java unicode

嘿所有,我刚开始尝试学习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);
}
}
Run Code Online (Sandbox Code Playgroud)

令我困惑的是声明,char half ='\ u00AB'.该书指出\ u00AB是符号"1/2"的代码.如上所述,当我从cmd编译并运行程序时,在此行上生成的符号实际上是'1/2'.

所以一切似乎都在起作用.我决定玩代码并尝试一些不同的unicodes.我搜索了多个unicode表,发现它们都不符合上述结果.

在每一个我发现它声明代码/ u00AB不是'1/2'并且事实上是这样的:

http://www.fileformat.info/info/unic...r/ab/index.htm 那么Java使用的字符集是什么,我认为UNicode应该就是那个,Uni,只有一个.我搜索了几个小时,无处可以找到状态/ u00AB等于1/2的字符集,但这是我的java编译器将其解释为.

我必须在这里遗漏一些明显的东西!谢谢你的帮助!

axt*_*avt 16

这是Windows平台上控制台编码不匹配的一个众所周知的问题.

Java Runtime期望系统控制台使用的编码与系统默认编码相同.但是,Windows使用两种单独的编码:ANSI代码页(系统默认编码)和OEM代码页(控制台编码).

所以,当您尝试Unicode字符写入U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK到控制台,Java运行时预计,控制台的编码是ANSI编码(即Windows的1252你的情况),在此Unicode字符表示为0xAB.但是,实际的控制台编码是OEM编码(在您的情况下为CP437),其中0xAB表示½.

因此,将数据打印到Windows控制台System.out.println()会产生错误的结果.

要获得正确的结果,您可以使用System.console().writer().println().


ayu*_*ush 2

Java 的一大优点是它基于 unicode。这意味着,您可以使用非英语字母书写系统中的字符(例如中文或数学符号),不仅可以在数据字符串中使用,还可以在函数和变量名称中使用。

\n\n

下面是在类名和变量名中使用 unicode 字符的示例代码。

\n\n
class \xe6\x96\xb9 {\n    String \xe5\x8c\x97 = "north";\n    double \xcf\x80 = 3.14159;\n}\n\nclass UnicodeTest {\n    public static void main(String[] arg) {\n        \xe6\x96\xb9 x1 = new \xe6\x96\xb9();\n        System.out.println( x1.\xe5\x8c\x97 );\n        System.out.println( x1.\xcf\x80 );\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

Java 是在 Unicode 标准为更小的字符集定义值的时候创建的。当时人们认为 16 位足以编码所有需要的字符。考虑到这一点,Java 被设计为使用 UTF-16。事实上,char数据类型最初是用来表示16位Unicode代码点的。

\n\n

UTF-8 字符集由 RFC 2279 指定;

\n\n

UTF-16 字符集由 RFC 2781 指定

\n\n

UTF-16 字符集使用 16 位数量,因此对字节顺序敏感。在这些编码中,流的字节顺序可以由 Unicode 字符“\\uFEFF”表示的初始字节顺序标记来指示。字节顺序标记的处理如下:

\n\n
When decoding, the UTF-16BE and UTF-16LE charsets ignore byte-order marks; when encoding, they do not write byte-order marks.\n\nWhen decoding, the UTF-16 charset interprets a byte-order mark to indicate the byte order of the stream but defaults to big-endian if there is no byte-order mark; when encoding, it uses big-endian byte order and writes a big-endian byte-order mark.\n
Run Code Online (Sandbox Code Playgroud)\n\n

另请参阅此

\n

  • UTF-8 和 UTF-16 **不是**字符集;它们是**相同字符集** Unicode 的两种不同的可变宽度编码。 (2认同)