java中 编码 解码 乱码 解惑

来源:互联网 发布:淘宝仅退款被判刑 编辑:程序博客网 时间:2024/05/11 20:22

首先说一下,乱码的英语是mojibake!


java编程中,关于编码有三个地方需要弄清楚,java源文件、class文件、虚拟机


java源文件

   源文件可以是任何编码的文件,这取决于保存形式。所以编译时需要指明源文件的编码方式,比如 javac -encoding utf8 HelloWorld.java,如果不指定,默认是操作系统编码。

    本来java读取文件跟文件编码无关,但是,在javac编译过程中,存在将二进制解码为字符,然后再将字符编码为二进制的过程,所以需要指定源文件的编码方式。


class文件

 无论源文件的编码格式是什么,class文件都是modified UTF-8,modified utf-8是java对utf-8作了修改的版本,正因为class文件的编码方式的统一,所以class文件才会跨平台


modified utf-8与传统utf-8的的异同:在基本平面内也就是字符u+0000-u+FFFF范围内,都是一样的存储方案。在增补平面内,modified utf-8是用6个字节表示一个字符,utf-8,使用4个字节表示一个字符。这是因为java发布的时候,unicode的基本平面,还远远没有满,modified utf-8将增补平面内的字符,分解为两个代码点比如0xyyy,0xzzz,每个代码点使用3个字节表示,所以就是一共6个字节。


java虚拟机编码

  java虚拟机的编码是utf-16,双字节表示一个字符,请切记java虚拟机中的编码方式是utf-16


java生命周期

java源文件---->class 文件------->jvm(输入流、输出流)---------->控制台

上述任何一个阶段,都会存在编码解码,只要存在编码解码就会存在乱码的问题。


编译java文件与-encoding:
     可以指定java文件的编码方式。编译java文件时默认采用操作系统编码,在中文操作系统下是gbk;如果java文件是gbk没有问题。但是,如果java源文件是utf8,那么就会出现编译错误

设置javac -encoding gbk HelloWorld.java,就可解决此错误;明白了-encoding的作用,我们也就能明白
“为什么eclipse编译不会出现乱码”了。这是因为eclipse在编译java文件时,它识别了java源文件的编码,然后传入-encoding参数,这就等同于javac -encoding xx.java。所以即使一个java project中,有不同的编码java文件,编译后,仍然不会出现乱码问题;

class文件:
在任何平台下都是改良版的utf8,从而保证了java的跨平台性。
jvm:
jvm编码都是Unicode(utf-16)编码

控制台:
我们经常会windows控制台出现乱码,这是因为控制台编码是GBK,如果java程序的-Dfile.encoding=utf8 定义输出的流是utf-8编码的,windows控制台不会自动转换,所以就会出现乱码,如果设置将-Dfile.encoding=GBK就不会乱码了。当然反过来说,如果控制台可以自动转换,从utf8转换为gbk,那么也不会出现乱码。
请看下边我做的测试:
[html] view plaincopy
  1. public class HelloWorld{  
  2.       
  3.     public static void main(String[] args){  
  4.         System.out.println("哈哈");  
  5.     }  
  6. }  






问题:

  byte[] arr = "x".getBytes();

这句程序的意思是,返回字符串x在操作系统默认编码方案下的字节数组,通常情况下,中文操作系统是gbk,英文操作系统是iso8859-1,可以通过-Dfile.encoding=xx,来影响操作系统的默认编码(jvm认为的操作系统编码),通过查看源码会发现,这个设置最终会影响Charset.defaultCharset()

关于-Dfile.encoding与charset.defaultcharset(),可以参考我的另一篇博文-Dfile.encoding与Charset.defaultCharset()关系



说到最后,我们应该如何防止乱码呢?
1、开发中,将所有文件保存为utf8,
2、设置 jvm  -Dfile.encoding=UTF8,不再依赖操作系统默认的编码方式。
  2.1 eclipse下,window--->preferences---->installed jres---->edit--->-Dfile.encoding=UTF8
  2.2 Tomcat单独启动,windows系统下,修改catalina.bat,设置 set JAVA_OPTS=-Dfile.encoding=UTF8
这样设置,jvm输入、输出流默认都会以utf8编码、解码!

0 0
原创粉丝点击