Java编码详解

     Java编码

     对于使用中文以及其他非拉丁语系语言的开发人员来说,经常会遇到字符集编码问题。对于Java语言来说,其内核和class文件使用的是UCS2编码(2个字节的Unicode编码)。这种编码并不属于某个语系的语言编码,它实际上是一种编码格式的世界语。在这个世界上所有可以在计算机中使用的语言都有对应的UCS2编码,这使Java程序具有良好的跨平台性。

正是因为Java采用了UCS2,因此,在Java中可以使用世界上任何国家的语言来为变量名、方法名、类起名。例如下列的 人.java:

 首先Java(包括JSP)源文件中很可能包含有中文,而Java和JSP源文件的保存方式是基于字节流的,Java编译器在对源文件编译前,会先把源文件转换为unicode编码,因为这个原因,我们在编译时一定要把源文件用的是什么编码方式正确无误的“告诉”编译器,如果Java和JSP编译成class文件过程中,使用的编码方式与源文件的编码不一致,就会出现乱码。

我们常常没有用到encoding这个参数。其实encoding这个参数对于跨平台的操作是很重要的。如果没有指定encoding,则按照系统的默认encoding,gb平台上是gb2312,英文平台上是iso8859_1。
       java的编译器实际上是调用sun.tools.javac.main的类,对文件进行编译,这个类有compile函数中间有一个encoding的变量,-encoding的参数其实直接传给encoding变量。编译器就是根据这个变量来读取java文件的,然后把用utf-8形式编译成class文件。

对于上面代码,源文件是使用utf-8的,则手动编译的时候就使用如下方法:

javac -encoding utf-8 -d . 人.java

反之,如果使用javac -encoding gbk -d . 人.java,则会出现编译错误,如下:

使用错误的的编码方式编译java源文件出现的错误信息

 

以上只出现在手动编译时,如果使用的是Eclipse等带编译功能的IDE,则只需设置源文件的编码方式就可以了。

以下引用网上的一段关于Java编码的解释

     “首先,javac看命令行中有没有用-encoding参数指定一个字符集,没有,则用系统环境中指定的字符集。接下来javac开始解释源码文件,遇到多字节的字符,就用前面确定的字符集编码来解释,并转换为unicode,写入.class 的字节码文件里面。
好了,下面我们要运行这个class文件了,jvm启动后读入class字节码,那些个中文字符串都以unicode表示,这没什么可说的,在哪都一样(平台无关的)。下面可能需要输出这个字符串到其它的应用程序了:控制台/文件/socket等等等等....这样jvm首先要检查操作系统的 encoding(注意,jvm从字节码里面完全不知道这些字符串是什么编码的,全是unicode),然后按该encoding来解释这些 unicode码到操作系统的encoding。当然,对于特殊的环境jvm也许不去检查操作系统的encoding,而是从环境变量里面读,这样你就可以控制jvm执行时的目的encoding了。”

 

Java编码转换

 实现上,当我们从IDE输入“哈哈”时,用的是java源代码文件保存的格式,一般是utf-8,有时也可是GBK,而在Java编译程序时,会不由分说地将所有的编码格式转换成utf-8编码,读者可以用UltraEdit或其他的二进制编辑器打开上面的“人.class”,看看所生成的二进制是否有utf-8的编码(utf-8和ucs2之间的转换非常容易,因为utf-8和ucs2之间是用公式进行转换的,而不是到代码页去查,这就相当于将二进制转成16进制一样,4个字节一组)。如“哈哈”的utf-8编码按着GBK解析就是“鍝堝搱”。

下面的代码将输出“鍝堝搱”。

String str = "哈哈";

System.out.println(new String(str.getBytes("utf-8"), "gbk"));   

由于将“哈哈“的utf-8编码格式按着gbk解析,所以会出现乱码。

如果要返回中文的UCS2编码,可以使用下面的代码:

System.out.println(str.getBytes("unicode")[2]);

System.out.println(str.getBytes("unicode")[3]);

前两个字节是标识位,要从第3个字节开始。"哈"的UCS2编码就是54c8.

 

Java属性文件

Java中的属性文件只支持iso-8859-1编码格式,因此,要想在属性文件中保存中文,就必须使用UCS2编码格式("uxxxx),因此,出现了很多将这种编码转换成可视编码和工具,如Eclipse中的一些属性文件编辑插件。也可以使用jdk自带的根据native2ascii.exe,使用方法是在cmd中输入

native2ascii -[options] [inputfile [outputfile]]

说明:

           -[options]:表示命令开关,有两个选项可供选择
             -reverse:将Unicode编码转为本地或者指定编码,不指定编码情况下,将转为本地编码。
             -encoding encoding_name:转换为指定编码,encoding_name为编码名称。
 
           [inputfile [outputfile]]
             inputfile:表示输入文件全名。
             outputfile:输出文件名。如果缺少此参数,将输出到控制台。

      下面的代码是用Java实现native2ascii的功能
附:
    utf-8和unicode之间的转换

      在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 0xxxxxxx
      在Unicode中编码为 0080 - 07FF 的 UTF-8 中编码形式为: 110xxxxx 10xxxxxx
      在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值