您好,欢迎访问三七文档
第1页JAVA编码原理分析1JAVAUnicode编码的含义Unicode是一种在计算机上使用的字符编码,它为每种语言的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的请求。Unicode的目的就是能支持世界上所有的字符集,也就是说几乎所有的字符集包含在字符在unicode中都有对应的编码。而我们平常所说的UTF-8和UTF-16就是unicode编码的两种实现方式。在java中,每一个string都是unicode编码。为什么string在JAVA中是unicode编码呢?原因在于string在保存的过程中是用char[]数组保存数据的,所以string可以看出是由char组成的数组,而一个字符(char)就是双字节的unicode编码,所以string也是unicode编码。1.1操作系统每个操作系统都有其特定的编码方式。在java中,System.getProperty(“file.encoding”);语句可以获取系统默认编码方式。1.2JVMJava具备有跨平台的特性,要想实现跨平台功能,就需要用到JVM,在java第2页中,JVM采用的是unicode编码。总的来说,JVM是和操作系统打交道的。在不同的机器平台,编码方式都是不同的,为了使程序能够在各个机器平台上能够执行,JVM在执行class文件的字节码时,就把字节码解析成具体平台上的机器指令,也就是目标代码。1.3源代码Java源代码的编码方式可以设定。比如中文的GBK编码,国际码UTF-8等。而为了避免出现乱码的情况,在java编码的过程中,源代码文件使用什么编码方式编码,在解码的时候就应使用相对应的编码方式解码。2JAVA编码分析JAVA涉及编码的地方很多,从源代码到输出要经过多次编解码,从流程上可以划分为三种情况:1)源代码-》JavaClass文件-》内部处理-》控制台输出。2)控制台输入-》内部处理。3)外部输入-》内部处理-》外部输出。内部处理包括getBytes()、newString()等。2.1源代码编码过程Java源代码在编译的过程中,JDK会根据编译参数来编码源代码字符集。如果不指定编码格式参数,系统会根据操作系统的file.encoding参数来获取操作系统的编码格式,然后把源代码的字符集编译成字节码文件,再保存到内存当第3页中,最后把保存好的内存信息写入class文件,生成二进制文件。2.2JavaClass编码过程Class文件其实也是字节码文件,class文件信息保存为unicode格式。而class文件是不能在操作系统中直接运行的,必须依赖于JVM进行解释执行。Class文件的字符流用getBytes()将字符串中的字符char按照特定的编码格式进行编码,最后得到byte[]数组。最终,JVM在执行class文件的字节码时,把字节码解释成具体平台上的机器指令执行。这就是java一次编译,到处运行的原因。2.3getBytes()编码过程getBytes()和newstrin()是java编码的两个重要的方法。这两个方法都是相对于string()而言的,即是相对于字符串而言的。getBytes()方法可以指定string类的编码方式。其中getBytes()又有有参数和无参数之分。有参数的getBytes()就是按照参数设定的编码格式转换string。无参数的getByte()是:用平台的默认字符集将此String编码为byte序列,并将结果存储到一个新的byte数组中。但这里的平台不是操作系统,“平台默认的编码格式”也非操作系统所用的编码。在这里所说的“平台默认的编码”是指当前”.java”文件的编码。比如有一个名为Test.java的.java文件,使用的编码是UTF-8,那么,使用String.getBytes()时,默认使用的编码就是UTF-8。2.4newString()编码过程从上面可知,getBytes()方法是将字符串的字符进行编码。而newstring()第4页则刚好相反,这是一个解码的方法。newString(byte[]bytes,Stringcharset)是将byte数组按照charset去解码,将解出来的一个个字符用unicode字符存储,并返回这个unicode字符串。2.5控制台输出过程当JVM和操作平台打交道结束后,如果要把结果输出到控制台,就必须把byte[]的字节流以newstring()的形式解码成正确的字符串集。在把string从控制台输入。2.6控制台输入过程Java中的string使用getBytes()方法把字符集按照特定编码方式编码成byte[],再送入控制台进行数据处理。3乱码场景分析3.1控制台输出乱码现在我们用代码测试一下控制台输出乱码的情况,首先我们先运行图3.1的代码:第5页图3.1代码运行的结果如图3.2:图3.2上面的代码测试的是字符串str=”编码测试”在不同的编码方式下的编码情况。由上面的代码可知,在GBK编码中,一个中文是两个字节,而UTF-8是一个中文三个字节。最后发现,在控制台输出结果的时候,str2字符串出现了乱码情况。这是因为str2是使用getBytes()设定的编码方式,即UTF-8实现编码,而newstring()则是通过平台默认的字符集来实现解码。在这里,平台默认的编码字符集为GBK,所以在解码的过程中产生了乱码。3.2日志输出乱码3.3数据库读取现乱码第6页3.4写数据库出现乱码3.5JSP读取参数出现乱码在编程中,JSP乱码情况会经常遇到。对于JSP编码来说,我们要学会区分pageEncoding和contentType中的charset两种编码情况。pageEncoding是JSP页面本身的编码,contentType的charset是指服务器发送客户端时的内容编码。JSP要经过两次编码,第一次是JSP编译成java文件,它会根据pageEncoding的设定来读取JSP,结果由统一的编码方案编译成统一的UTF-8的java源码(即java)。如果pageEncoding设定错了,或者没设定,出来的就是中文乱码。现在看代码的运行结果,JSP代码如图3.3:图3.3其中的JSP文件是用UTF-8编码的,但pageEncoding的设定为GBK,然后我们看一下运行结果,如图3.4图3.4第7页发现“人生自古谁无死”这句话乱码了。这就是因为pageEncoding设定错误造成的JSP读取参数出现乱码。3.6JSP页面出现乱码上一节说了,JSP要经过两次编码,而第二次编码就是服务器发送给客户端时的内容编码。也就是contenType中charset设定的编码。下面再来看一下,由charset设定不当引起的页码出现乱码的情况,先看下面图3.5原码:图3.5上面的charset的设定为”ISO-8859-1”编码,现在看一下运行结果,如图3.6:图3.6这时候整个页码有关中文的地方都成了乱码,这是因为服务器端发给客户端的编码方式不包含中文字符集,所以造成JSP页码显示出现乱码。
本文标题:JAVA编码分析
链接地址:https://www.777doc.com/doc-2881392 .html