Chinaunix首页 | 论坛 | 博客
  • 博客访问: 586376
  • 博文数量: 155
  • 博客积分: 7055
  • 博客等级: 少将
  • 技术积分: 1700
  • 用 户 组: 普通用户
  • 注册时间: 2004-11-22 11:40
文章分类

全部博文(155)

文章存档

2016年(1)

2011年(2)

2010年(1)

2009年(2)

2008年(9)

2007年(39)

2006年(58)

2005年(38)

2004年(5)

我的朋友

分类: Java

2007-02-12 21:17:19

一、java源码的编辑,编译。//070212 未完待续

编辑一个java源文件a.java:
class a {
        public static void main(String[] args) {
                String s = "世世世世世世";
                System.out.println(s);
        }
}
在windows xp中文版中,(默认file.encoding=GBK) 编译OK。

在linux 中,locale环境为 LANG=en_US; LC_ALL=C 时,编译出错:
a.java:3: warning: unmappable character for encoding ASCII
                String s = "????????????";
                               ^

这是为什么呢?

java的class文件使用的是UTF-8编码。
a.java被编译到a.class 的过程,包含到 UTF-8编码转换的过程。
在这里,就是从 C -> UTF-8。

The locale "C" or "POSIX" is a portable locale; its LC_CTYPE part corresponds to the 7-bit ASCII character set.
计算机是以数字作为处理对象。所以java源码里的字符在被处理之前,计算机要将它转换成相应的数字。这种 字符-数字 的对应关系可以理解为character set。
locale C的字符集只定义了数字0~127所对应的字符,也就是说 > 0x7F 的数值,它就不认识了。(红色的数字)

sh-3.00# hexdump -C a.java 
00000000  63 6c 61 73 73 20 61 20  7b 0a 09 70 75 62 6c 69  |class a {..publi|
00000010  63 20 73 74 61 74 69 63  20 76 6f 69 64 20 6d 61  |c static void ma|
00000020  69 6e 28 53 74 72 69 6e  67 5b 5d 20 61 72 67 73  |in(String[] args|
00000030  29 20 7b 0a 09 09 53 74  72 69 6e 67 20 73 20 3d  |) {...String s =|
00000040  20 22 ca c0 ca c0 ca c0  ca c0 ca c0 ca c0 22 3b  | "............";|
00000050  0a 09 09 53 79 73 74 65  6d 2e 6f 75 74 2e 70 72  |...System.out.pr|
00000060  69 6e 74 6c 6e 28 73 29  3b 0a 09 7d 0a 7d 0a     |intln(s);..}.}.|

解决方法:
1 加上编译选项 -encoding charset, charset可为任意 定义了0~255对应字符 的字符集。
2 设置Locale. 

验证class文件里的编码
选择charset为 iso88591 来编译, locale环境为 LANG=en_US; LC_ALL=en_US.iso88591
sh-3.00# hexdump -C a.class
00000000  ca fe ba be 00 00 00 31  00 1d 0a 00 06 00 0f 08  |漱壕...1........|
00000010  00 10 09 00 11 00 12 0a  00 13 00 14 07 00 15 07  |................|
00000020  00 16 01 00 06 3c 69 6e  69 74 3e 01 00 03 28 29  |........()|
00000030  56 01 00 04 43 6f 64 65  01 00 0f 4c 69 6e 65 4e  |V...Code...LineN|
00000040  75 6d 62 65 72 54 61 62  6c 65 01 00 04 6d 61 69  |umberTable...mai|
00000050  6e 01 00 16 28 5b 4c 6a  61 76 61 2f 6c 61 6e 67  |n...([Ljava/lang|
00000060  2f 53 74 72 69 6e 67 3b  29 56 01 00 0a 53 6f 75  |/String;)V...Sou|
00000070  72 63 65 46 69 6c 65 01  00 06 61 2e 6a 61 76 61  |rceFile...a.java|
00000080  0c 00 07 00 08 01 00 18  c3 8a c3 80 c3 8a c3 80  |........????|
00000090  c3 8a c3 80 c3 8a c3 80  c3 8a c3 80 c3 8a c3 80  |????????|
000000a0  07 00 17 0c 00 18 00 19  07 00 1a 0c 00 1b 00 1c  |................|
000000b0  01 00 01 61 01 00 10 6a  61 76 61 2f 6c 61 6e 67  |...a...java/lang|
000000c0  2f 4f 62 6a 65 63 74 01  00 10 6a 61 76 61 2f 6c  |/Object...java/l|
000000d0  61 6e 67 2f 53 79 73 74  65 6d 01 00 03 6f 75 74  |ang/System...out|
000000e0  01 00 15 4c 6a 61 76 61  2f 69 6f 2f 50 72 69 6e  |...Ljava/io/Prin|
000000f0  74 53 74 72 65 61 6d 3b  01 00 13 6a 61 76 61 2f  |tStream;...java/|
00000100  69 6f 2f 50 72 69 6e 74  53 74 72 65 61 6d 01 00  |io/PrintStream..|
00000110  07 70 72 69 6e 74 6c 6e  01 00 15 28 4c 6a 61 76  |.println...(Ljav|
00000120  61 2f 6c 61 6e 67 2f 53  74 72 69 6e 67 3b 29 56  |a/lang/String;)V|
00000130  00 20 00 05 00 06 00 00  00 00 00 02 00 00 00 07  |. ..............|
00000140  00 08 00 01 00 09 00 00  00 1d 00 01 00 01 00 00  |................|
00000150  00 05 2a b7 00 01 b1 00  00 00 01 00 0a 00 00 00  |..*?.?........|
00000160  06 00 01 00 00 00 01 00  09 00 0b 00 0c 00 01 00  |................|
00000170  09 00 00 00 2b 00 02 00  02 00 00 00 0b 12 02 4c  |....+..........L|
00000180  b2 00 03 2b b6 00 04 b1  00 00 00 01 00 0a 00 00  |?.+?.?.......|
00000190  00 0e 00 03 00 00 00 03  00 03 00 04 00 0a 00 05  |................|
000001a0  00 01 00 0d 00 00 00 02  00 0e                    |..........|
000001aa

sh-3.00# echo -n  世 | iconv -f iso88591 -t utf8 | hexdump -C
00000000  c3 8a c3 80                                       |??|
00000004

sh-3.00#  echo -n ?|iconv -f iso88591 -t utf8 |hexdump -C
00000000  c3 8a                                             |?|
00000002 
// 上面命令中的?,是在secureCRT中输入汉字“世”,然后删掉后半个汉字。

参考:
* O'Reilly - Learning Java, 3rd Edition
* man 3 setlocale
* 车东  强烈推荐

阅读(2365) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~