`
zhtch_123
  • 浏览: 83345 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

java字符编码原理浅析

 
阅读更多

 

本周遇到一个java乱码问题,于是对java的编码问题做了一些实验和了解。简单分析如下:

先看下如下代码:

import java.io.UnsupportedEncodingException;

public class CharSetTest {

public static void main(String[] args) throws UnsupportedEncodingException {

String test = " 篮球 " ;

byte [] defaultResult = test.getBytes();

for ( byte e : defaultResult) {

System. out .print(e + " " );

}

System. out .println(System. getProperty ( "file.encoding" ));

System. out .println( "test=" + test);

}

}

1.执行 javac CharSetTest.java,能正常编译,但是得到如下警告:
CharSetTest.java:5: warning: unmappable character for encoding ASCII
String test = "????";

分析一下为什么会这样呢?对于java编译器来说,CharSetTest.java就是一个文本文件,java编译器要解析 这个文本文件并编译生成.class文件。分析了下原因大概是这样的:CharSetTest.java一定是以某一种编码格式来存储的,所以java编 译器一定要知道该文本文件时用什么来编码的,如果没有指定就用默认认为文件的编码格式是” ANSI_X3.4-1968”(不同环境可能不一样),所以就会发现无法解释的中文而出现了乱码。
那么以上问题该如何解决,就是要在编译的时候告诉编译器,需要编译的java文件的编码格式,否则编译器有可能遇到不能理解的字符就当做乱码处理了。由于 CharSetTest.java是GBK格式的,所以通过如下命令完成:
Javac CharSetTest.java –encoding=GBK。

2. 通过执行Javac CharSetTest.java –encoding=GBK,已经能得到正确的class文件了,但是执行 java CharSetTest,结果如下:
63 63 ANSI_X3.4-1968
test=??

那么既然已经正确编译了,为什么得到的输出结果还会是乱码呢?前面已经可以肯定.class文件里面存放的中文字符串是正确的了,那原因肯定是在JVM 从.class文件读取这个字符串字节流并构建String对象的时候采用了错误的字符编码来构建字节流。进而导致从JVM输出字符串的字节流到我们控制 台的时候,出现乱码。那么很显然,我们必须告诉jvm我们控制台的编码,或者我们希望它采用什么字符编码来构建字节流。如果没有告诉jvm,那么文件的编 码格式是” ANSI_X3.4-1968”(不同环境可能不一样)。
假设我们控制台是GBK的编码,那么只要我们正确告诉它,它就能正确的返回字节流了。那么原因就比较简单,我们没有正确告诉JVM我们需要它构造字符串 输出流的时候应该采用的编码格式。那么该如何处理呢?通过如下命令:
java -Dfile.encoding=GBK CharSetTest
得到结果:
-64 -70 -57 -14 GBK
test=篮球
以上试验在eclipse下面并不会成立,因为eclipse会帮我们做一些判断。同时不同的环境可能也不 一样。

最后总结:
Java的class文件采用UTF-8,在JVM里面采用UTF-16。整个过程中编码转换大概可以看下图:

 

java encode

 

 

 

从上图可以理解不管采用那种格式的源文件,只要正确告诉编译器,编译器就会得到正确的结果。同时只要告诉JVM正确的输出流需要的编码格式,JVM总会返 回正确编码格式的输出流。


那么要想不产生乱码要注意两个环节:
1. 告诉编译器你的源文件编码。
2. 告诉jvm你显示或者构造字符串输出流时希望的编码。
尤其JSP乱码时要注意request请求采用的编码和解析request时候采用的编码是否一致,response的编码和html charset的编码是否一致。

同时我们常遇到jsp、数据库等乱码问题可以找一下是否是以下两种原因:
1. 误解型:a文件是GBK编码,但是你以为是UTF-8型编码,所以用UTF-8来理解它,就会出现乱码。
2. 无能为力型:a文件时GBK编码,你也知道它是GBK编码,但是你想转换成ISO-8859-1的方式来显示,但是GBK里面有很多字符时ISO- 8859-1所不能解释的,这时也会出现乱码。

分享到:
评论

相关推荐

    Java中文乱码浅析及解决方案

    这个问题通常源于字符编码的不一致,即不同环节采用的字符编码标准不统一。本文将深入探讨这一问题,并提供相应的解决方案。 首先,我们要理解Java编译器编码与运行环境编码的差异。Windows系统通常使用GBK或GB2312...

    浅析Java 常用的 4 种加密方式(MD5+Base64+SHA+BCrypt)

    Base64 是一种常用的编码方式,可以将二进制数据转换为 ASCII 码。Base64 加密的特点是可以将任意长度的数据转换为一个固定长度的字符串。Java 中可以使用 Base64 类来实现 Base64 加密。 Base64Util 是一个工具类...

    基本数据类型存储格式浅析

    在ASCII编码中,一个字符占用1个字节(8位),包含128个不同的字符。而在Unicode编码中,如UTF-8,字符可能占用1到4个字节,以支持更多语言和特殊字符。 4. 布尔型(Boolean) - 布尔型在很多语言中如Java和Python...

    Android JNI 浅析

    此外,JNI提供了多种数据类型转换工具,比如`NewGlobalRef`和`DeleteGlobalRef`来管理Java对象的引用,`NewStringUTF`和`GetStringUTFChars`处理字符串,以及`CallVoidMethod`、`CallIntMethod`等调用Java方法的函数...

    浅析12306售票算法(java版)

    《12306售票算法解析(Java版)》 12306是中国铁路客户服务中心的官方网站,其售票系统采用了一种独特的算法来处理庞大的购票需求...在Java版本的实现中,主要通过字符串操作来模拟座位的状态变化,简化了问题的抽象。

    浅析Node.js查找字符串功能

    5. 由于文件可能包含二进制内容,读取文件时应指定正确的编码(如"utf-8"),以确保字符串可以正确匹配。 通过上述方法,即使项目文件数量庞大,我们也可以迅速定位到含有特定字符串的文件。并且,Node.js的执行...

    浅析Java IO相关知识点

    总之,Java IO涉及的内容广泛,包括流、缓冲、字符编码、对象序列化、文件操作、网络通信等多个方面。理解和掌握这些知识点对于编写高效、稳定的应用程序至关重要。无论是进行简单的文件读写,还是构建复杂的服务器...

    浅析Java编程中枚举类型的定义与使用

    Java中的枚举类型是面向对象编程中的一种特殊类型,它用于定义一组有限的、预定义的常量。枚举在Java中通过`enum`关键字来创建,它在很多方面类似于...通过枚举,开发者可以避免硬编码常量,确保代码的一致性和正确性。

    浅析数据库SQL注入及其安全防护.pdf

    其次是字符过滤,对用户输入的数据进行严格的筛选,排除那些可能被解释为SQL命令的特殊字符。最后是数据加密,通过加密技术可以有效保护数据传输过程中的安全,避免攻击者截获敏感信息。 在了解SQL注入的基本原理...

    浅析java中 Spring MVC 拦截器作用及其实现

    拦截器通常用于处理业务逻辑相关的预处理和后处理,而过滤器则更适合进行通用的请求和响应处理,如登录验证、字符编码转换等。 通过以上内容,我们可以理解Spring MVC拦截器的核心概念和实际应用,从而更好地利用这...

    浅析JAVA中过滤器、监听器、拦截器的区别

    比如,可以用来进行字符编码转换、请求日志记录、权限检查等。过滤器的生命周期与Web应用紧密相关,从Web应用启动时初始化,到Web应用停止或重新部署时销毁。在web.xml中配置Filter时,可以指定它拦截哪些请求,以及...

    浅析Java基于Socket的文件传输案例

    在这个例子中,`sendMessage()`方法使用`DataOutputStream`发送不同平台的标识(如0x1代表Windows,0x2代表Unix,0x3代表Linux)或者UTF编码的字符串。`getMessageStream()`方法返回一个`DataInputStream`实例,以便...

    ASP.NET Core 6 浅析环境变量与配置的优先级.rar

    环境变量通常用于存储不能或不应该在代码或配置文件中硬编码的敏感信息,如API密钥、数据库连接字符串或第三方服务的凭据。这是因为环境变量在大多数操作系统中都是安全的,并且可以在不修改应用程序代码的情况下...

    深入浅析Jsp中 out.print 和 out.write 的区别

    而write方法则适用于需要精确控制字符输出流的场景,比如在需要指定字符编码的情况下。 在开发JSP页面时,了解out.print()和out.write()的区别非常关键。正确的使用这两种方法,不仅可以避免出现...

    浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号

    这一点在使用JavaScript进行JSON数据处理时尤为重要,因为在JavaScript对象字面量和JSON字符串之间存在着紧密的联系。 不过,需要注意的是,尽管JSON规范明确要求不能有末尾逗号,但在实际应用中,尤其是JavaScript...

    浅析get与post的一些特殊情况

    本文将针对标题“浅析GET与POST的一些特殊情况”中的描述进行深入探讨。 1. GET方法: - 当使用GET方式提交表单时,表单数据会被附加到URL的查询字符串中,形如`?key1=value1&key2=value2`。在描述中提到的例子中...

    XSS转码 && struts2 property标签的bug

    最后,“浅析XSS漏洞原理.mht”文件可能深入探讨了XSS漏洞的基础概念,包括它的工作原理、危害性以及预防措施。文件可能还涵盖了常见的XSS防护手段,如使用HTTP头部的Content-Security-Policy(CSP)、输入验证、...

    Struts2入门教程。包括jquery集成等。入门必看

    - 返回结果:通过返回特定字符串来指示视图层如何响应。 - 输入参数:可以通过Action的属性直接接收HTTP请求中的参数。 #### 三、表单验证 - **手动完成输入校验**:开发者可以在Action中手动编写代码来检查输入...

Global site tag (gtag.js) - Google Analytics