`
trydofor
  • 浏览: 145566 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

JAVA乱码你知道(DIY)

阅读更多

1. 四个涉及编码的环节

 

java开发中的乱码问题,有4个环节:

1. java文件的编码。

2. class文件的编码。

3. jvm中的字符串编码。

4. 外部资源的编码。

 

2. java 文件的编码

 

java文件是可以指定编码的,默认是系统编码,如果GBK。

 

 

	public static void main(String[] args) {
		String s = "汉";
		System.out.println(s);
	}

 

文件以GBK保存。只要我们以 GBK打开文件,汉字部分就正常显示。

 

结论:java源文件可以任意编码

 

3.  class 文件编码

 

当 java文件编译成class时候,进行了一次编码转换。这里的例子是 GBK 到UTF8

也就是说 class文件是以UTF8格式保存的。

所以以UTF8打开这个class,我们能够看到这样的字符串:

“([Ljava/lang/String;)V 汉” 

当然,有些字符不能正确显示,需要以HEX查看。

 

结论:class文件是UTF8编码

 

4. jvm中的字符串编码。

 

    jvm中的字符串是 unicode的,或者叫 UTF16。(下面证据不太直接。)

 

String s1 = "汉";
String s2 = "お";
System.out.println(Integer.toString(s1.charAt(0), 16));
System.out.println(Integer.toString(s2.charAt(0), 16));
System.out.println(s1+s2);
 

5. 外部资源的编码

 

主要是各种可以和外部产生联系的输入和输出。

如,System.out/err/in这些是流,外部存在的文件(读入或写出)

 

System.out/err/in,默认使用系统编码集。

如,export LANG=en_US.UTF8

 

外部文件,在read或write时,指定合适的编码即可。

 

6. 字符集转换

 

字符集的转换很多时候会丢失信息,从而产生乱码。

因此,一定要有正确的编码集使字符串变为正确的unicode。

 

大家经常看到这样的东西:new String(input.getBytes("ISO-8859-1"), "GBK") 

发生了一下事情。

1) String(GBK) -->byte[](ISO-8859-1) -->JVM(UTF16)   这里是乱码

2) JVM(UTF16) -->byte[](ISO-8859-1) -->byte[GBK]-->JVM(UTF16) 这里转回来了。

如果是 String(GBK) -->byte[](GBK) -->JVM(UTF16), 那么就不会有乱码了。

 

7.  区分字符集和字体

 

有些时候,乱码是因为字体显示不正确造成的,这个赖不上字符集。

表象上:字体造成的乱码,一般表现为豆腐块,字符集表现为 问号。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics