码迷,mamicode.com
首页 > 其他好文 > 详细

JVM的字符表示

时间:2015-05-02 09:52:14      阅读:402      评论:0      收藏:0      [点我收藏+]

标签:字符   编码   

JVM在设计中是不允许多种编码方式并存的。这是因为如果在内存中Java字符可以有GBK、UTF-16等多种编码形式存在,那么对开发者来说,连打印字符串都寸步难行。例如,一个GB2312字符串后面跟了一个UTF-8字符串,那么连接后的最终结果是什么编码呢?

Java开发者必须牢记:在Java中,字符串只以一种形式存在,那就是Unicode(不选择任何特定的编码,直接使用他们在字符集中的编号,这是统一的唯一方法)。
但在Java中到底是指哪里呢?是指在JVM中,内存中,代码中声明的每一个char、String类型变量中。例如,在程序中写:

char han=‘永‘;

在内存的相应区域,这个字符就表示为0x6c38,可以用下面的代码证明:

char han=‘永‘;
System.out.format("%x",(short)han);

输出是6c38.反过来使用Unicode编号来制定一个字符也可以,像这样:

char han=0x6c38;
System.out.println(han);

输出是:永。

这其实也是说,只要你正确读入了“永”字,那么它在内存中的表示形式一定是0x6c38,没有任何其他值会代表这个字。

JVM的这种约定使得一个字符分为两部分:JVM内部和OS的文件系统。在JVM内部,统一使用Unicode表示,当这个字符被从JVM转到外部(保存为文件),就进行了编码转换,使用了具体的编码方案。因此可以说,所有的编码转换只发生在边界的地方,JVM和OS的交界处,也就是各种输入流/输出流(或者Reader,Writer类)起作用的地方。

所有的I/O基本上都分两大阵营:面向字符和面向字节。

面向字节,那么这类工作要保证系统中的文件二进制内容和读入JVM内存的二进制内容一致,不能变换任何0和1的顺序。这种输入/输出的方式很适合读入视频文件或者音频文件,或者任何不需要做变换的文件内容。

面向字符是希望系统中的文件字符和读入内存的字符一致。也就是说当我们从一个文本文件中读入字符的时候,这个字符如何编码暂且不看,我们需要的是,这个字符在读到内存里时,仍然是这个字符,不会乱。那从OS到JVM内存的过程中,其实是对字符进行了隐式的转换。

注意,上面提到过的ReaderWriter都是面向字符的I/O类,在输入输出的时候,都会使用自己默认的编码方式对文件进行转换。Reader和Writer的默认编码方式是GBK,这也就意味着,如果一个UTF-8文件使用Reader读入内存,它会使用GBK进行转换,那么打印出来的字符肯定不对。这是一种傻瓜式的功能提供方式,可能对大多数初级用户(不考虑跨平台)比较好用。

如果用到GBK编码以外的文件,就必须采用编码转换:一个字符与字节之间的转换。因此,Java的I/O系统中能够制定转换编码的地方,就是InputStreamReaderOutputStreamWriter类,他们是字节流和字符流的适配器,承担着编码转换的任务。

JVM的字符表示

标签:字符   编码   

原文地址:http://blog.csdn.net/langduhualangdu/article/details/45420479

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!