转自:http://blog.csdn.net/frank520/article/details/6865001

java乱码的原因,原理,解决方法.String odsStr = "测试";String newStr = new String(odsStr.getBytes("GBK"), "ISO8859_1");最近在编写Java程序的时候,偶尔会遇到中文字乱码的问题,或者偏僻字不能正常显示的问题,经过查找资料并通过几次测试,目前已经完全解决。首先需要说明一下我们经常用到的字符集,有ISO8859-1,GB2312,GBK,GB18030,UNICODE。这里ISO8859-1字符集只包含英文字符,使用一个字节存储。GB2312、GBK和GB18030字符集包含中文字符,他们都兼容ISO8859-1字符集,他们的字符存储格式是变长的,其中GB18030包含GBK,GBK包含GB2312。UNICODE包含世界上所有国家的字符,UNICODE又分为UTF-8,UTF-16和UTF-32三种,UTF-8是变长字符集,它兼容ISO8859-1,即英文字符使用一个字节编码,而其他的字符使用2到4个字节编码,其中中文字符大部分都是使用3个字节进行编码,少量偏僻字使用4个字节编码,UTF-16统一都使用2个字节编码,它不兼容ISO8859-1,英文字符也使用两个字节,UTF-32统一使用4个字节编码,也不兼容ISO8859-1,可见UTF-16和UTF-32都比较浪费空间。

乱码问题的产生最根本的原因就是使用错误的字符集解码字节流或者将给定的字符串用错误的字符集编码成错误字节流造成的,例如”中文”两个汉字,如果用ISO8859-1字符集将其编码为字节流,因为这个字符集不支持中文,所以就会出错,输出结果为3f3f,其意义就是??。再例如”中文”二字的GBK的字节流为d6 d0 ce c4,可是我们要是用不兼容的字符集去解码,例如用ISO8859-1或者UTF-8,这随后产生的字符串就是乱码,或者是其他的某个字符。从开发Java程序到运行Java程序的过程中都存在着编码问题,所以要想避免乱码产生,就必须了解在其中任何时候的编码处理的情况。源代码:在编写java源代码的时候,我们必须把编写的文本保存在文件中,这个时候不管用什么编辑器,都存在一个问题,就是以什么样的字符集将这些源代码(包含汉字)保存到文件中,大部分编辑器都会通过系统的环境变量得到系统的当前默认字符集,编辑器就会使用这个字符集将我们编写的源代码保存到文件中。一般我们的中文Windows系统的默认字符集是GB18030,AIX英文环境的默认字符集是ISO8859-1,AIX中文环境的默认字符集是IBM-eucCN。

编译:在编译.java文件的时候如果使用默认处理,则javac会使用系统当前的默认字符集去读取源文件,将源文件的内容转换为UTF-8编码,然后在进行编译,这时我们也可以通过-encoding参数指定一个字符集,让javac使用我们指定的字符集去读取源代码,然后编译。编译以后产生的class文件内部所有的中文字符都是用UTF-8的字符集进行编码的,这就是Java程序能处理任何国家文字的原因。运行时:Java程序在运行时,需要使用程序内部定义的中文字符串,也可能会使用从外部读取的中文字符串,这些经过处理,可能都会输出到程序外部,在这些过程中都涉及到编码的转换,程序内部定义的字符串都是用UTF-8存储的。而从外部读取和输出到程序外部的输出又使用什么字符集进行处理呢?在我们没有在程序中特别指定的情况下,JVM会根据系统属性确定使用哪个字符集,这个系统属性的名称为file.encoding,我们可以在启动java程序的时候通过-D参数设定这个值,如果没有设定,JVM会根据系统环境变量确定这个系统属性,一般我们的中文Windows系统的默认字符集是GB18030,AIX英文环境的默认字符集是ISO8859-1,AIX中文环境的默认字符集是IBM-eucCN。这样JVM在处理输入数据的时候就会把字节流根据这个参数进行解码,然后转成UTF-8格式,在Java程序内部处理,然后再根据这个参数把处理后的数据编码,输出到程序外部。这就是Java程序运行时字符集的使用情况。

现在有一个问题,我们平时都是Windows的中文环境下做开发,然后拿到AIX系统上去运行,AIX系统的默认语言环境是英文环境,这样就会出现乱码,分析过程如下:源文件编码格式为GB18030,默认编译,也采用GB18030读取源文件,正常转换为UTF-8,生成class文件,运行时没有进行特殊设置,语言环境为英文环境,默认编码为ISO8859-1,这样在输出中文的时候会把正常的UTF-8表示的汉字用ISO8859-1的字符集去编码生成字节流,因为ISO8859-1不支持汉字,结果输出的都是’?’。可是这个时候却发现,由外界输入给java程序的中文字符,却能正常输出,这又是为什么,其实这个也是运行时的默认字符集ISO8859-1造成的,Java程序运行时,在读取外部进入的字节流的时候,如果使用默认的读取方式,也是使用ISO8859-1的字符集进行解码处理,这样中间的处理过程中中文都已经不是原来的中文了,也就是说我们这个时候处理根本是我们认为的中文,而是一对乱码,虽然是乱码,但是其中的信息却没有丢失,在处理完后,在经过一次ISO8859-1的编码,又还原为正常的GB18030的编码输出,所有没有出现乱码。我们以前的解决方法是,在编译原文件的时候指定参数-encoding ISO8859-1,让编译器用ISO8859-1的字符集去解码源文件编译,然后运行程序,这时再输出程序的内部中文字符串也不是乱码了。看起来一切都解决了,可是却没有从根本上解决问题,class文件变得比平常大很多,程序中用到中文越多,class文件变大的越快。而且其中的中文信息也变味了。

另一个问题,如果我们正常编译程序,在AIX系统上线设定为中文环境,然后再运行Java程序,这样既不会使程序变大,也不会使中文变味,可是用了一段时间又发现问题了,处理过程中如果遇到偏僻的中文字,还是乱码,原因是AIX的中文环境使用的字符集是IBM-eucCN,我认为可能是这个字符集缺少偏僻汉字,无法解释其内容,所以偏僻字变成了乱码了。最后的解决办法是,在Windows中文环境下正常编写原程序,用默认的方式编译生成class文件,或者编译时指定参数-encoding GB18030,这样汉字都能正常解释并转换为UTF-8存储在class文件中,在运行的时候,我们需要制定参数,java –Dfile.encoding=GB18030 。。。。。,系统环境使用默认英文即可,这样JVM就不会根据系统的环境设定默认字符集,而是所有输入输出都使用我们指定的字符集,这样不但解决了英文环境下的中文输出问题,而且还解决了偏僻字的显示问题。

最后附上汉字的转码过程:1.‘中文’的GB18030编码为d6 d0 ce c4 对应java源码文件经过ISO8859-1解码为UTF-8为81 30 89 30 81 30 88 34 81 30 88 32 81 30 87 32 对应编译过程经过ISO8859-1编码为d6 d0 ce c4 对应Java程序输出汉字的过程d6 d0 ce c4经GB18030解释为‘中文’二字 对应系统显示汉字的过程。在这个过程中,虽然中间出现了乱码,但是信息没有丢,最后还是能还原为中文的,是比较蹩脚的处理过程。2. ‘中文’二字的UTF-8编码为e4 b8 ad e6 96 87,对应正常编译后的class文件存储内容经过ISO8859-1编码为3f 3f,已经出错,丢失信息,对应java程序汉字输出过程3f 3f经GB18030解释为汉字为??,乱码,无法还原, 对应系统显示汉字的过程这个过程中,信息丢失,是个完全错误的处理过程。3. ‘中文’的GB18030编码为d6 d0 ce c4 对应java源码文件经过GB18030解码为UTF-8为e4 b8 ad e6 96 87 对应编译过程经过GB18030编码为d6 d0 ce c4 对应Java程序输出汉字的过长d6 d0 ce c4经GB18030解释为‘中文’二字 对应系统显示汉字的过程。这个过程是最为理想的处理过程,没有丢失信息,也没有出现任何蹩脚的信息。

java乱码中文变为问号_转 java 中文 乱码 问号相关推荐

  1. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  2. java碰到乱码如何解决方法_如何处理java的乱码

    为什么说乱码是中国程序员无法避免的话题呢?这个首先要从编码机制上说起,大家都是中文和英文的编码格式不是一样,解码也是不一样的! 如果中国的程序员不会遇到乱码,那么只有使用汉语编程.汉语编程是怎么回事, ...

  3. java byte char io流_吃透Java IO:字节流、字符流、缓冲流

    前言有人曾问fastjson的作者(阿里技术专家高铁):"你开发fastjson,没得到什么好处,反而挨了骂背了锅,这种事情你为什么要做呢?" 高铁答道:"因为热爱本身, ...

  4. java web 开发之道_《Java Web开发之道》PDF 下载

    图书目录: 第1篇  编程 经验与 感悟篇 第1章  编程 经验谈6则 经验01  乐不思蜀--寻找编程的乐趣 经验02  水滴石穿--编程学习 经验谈 经验03  举足轻重--代码规范 经验谈 经验 ...

  5. java itext 导出pdf文件_【Java,PDF】使用Itext实现PDF文件生成

    重要声明:本文章仅仅代表了作者个人对此观点的理解和表述.读者请查阅时持自己的意见进行讨论. 前言 有时候,业务系统要求提供一个PDF文件导出的功能,这时候我们就需要将数据库的对应数据查询出来,然后生成 ...

  6. java 多态判断非空_收藏Java 面试题全梳理

    脚本之家 你与百万开发者在一起 来源 | Java建设者(ID:javajianshe) 作者 |cxuan 如若转载请联系原公众号 Java 基础篇 Java 有哪些特点 并发性的:你可以在其中执行 ...

  7. java用spring图书管理系统_基于Java + SpringMVC的图书管理系统

    需求分析 基于Java+SpringMVC的图书管理系统, 实现读者和管理员登陆,图书的增删改查,读者的增删改查,借还图书,密码修改,卡号挂失,超期提醒等功能 本站提供了其他类型的 图书管理系统源代码 ...

  8. java list 前100个_实现java 中 list集合中有几十万条数据,每100条为一组取出

    解决"java 中 list集合中有几十万条数据,每100条为一组取出来如何实现,求代码!!!"的问题. 具体解决方案如下: /** * 实现java 中 list集合中有几十万条 ...

  9. java设计一个查询模块_采用Java实现的汉语拼音查询模块

    0引言现有管理信息系统的数据库中存储了大量的中文信息,中文信息的检索是MIS的重要功能,对于中文字段的常见查询方法是输入汉字字符串,但是此方法需要过多的击键次数,例如,查询人名为"王晓明&q ...

  10. java计分系统编程代码_使用Java代码对实时系统进行编程

    由于许多重要原因,Java语言在实时系统中的使用并不广泛. 这些包括Java语言设计固有的不确定性性能影响,例如动态类加载,以及Java Runtime Environment(JRE)本身,例如垃圾 ...

最新文章

  1. 哪里可以找到python的免费教程-哪里可以找到比较靠谱的Python教程?
  2. 笔趣看小说全部章节爬取实战
  3. 学java_如何一步一步的学Java
  4. JDBC链接MySQL和Oracle
  5. win10开启oracle服务器配置,Windows环境(Win10)下安装、配置服务器类Oracle Database 11g Release 2...
  6. Keras-10 【Seq2Seq示例】数字转中文大写
  7. 安装Python第三方库方法总结
  8. python系统下载-python
  9. memcached—认识Memcache
  10. 浙江利捷分析报告(0612)
  11. 流量宝刷流量怎么操作不会被搜索引擎惩罚
  12. xcode 打包ipa
  13. KITTI数据集calib文件解析
  14. 《后端》bug: java.lang.IllegalArgumentException: geronimo.jta.1.1.spec: Invalid module name: ‘1‘ is not
  15. wordpress优化title的seo技巧
  16. nagios监控安装配置
  17. 天盾linux数据恢复,天盾Linux数据恢复软件
  18. Photoshop:使用层遮照制作图像渐变特效(2)
  19. python做相册_用Python和Conky做个电子相册,美化你的Linux桌面
  20. “泰迪杯”挑战赛 -利用非侵入式负荷检测进行高效率数据挖掘(完整数学模型)

热门文章

  1. 植保飞行器(G 题)--2021 年全国大学生电子设计竞赛
  2. tftp协议 服务器怎么返回错误信息,tftp执行流程
  3. win7 计算机定时关机脚本,win7定时关机设置及命令
  4. Ubuntu下gcc安装及使用
  5. 2022年PMP培训机构如何挑选?哪家好?
  6. 基于深度学习生成音乐
  7. ns-3 教程 —— 入门
  8. gimp中文版教程_GIMP中文教程.pdf
  9. 韩顺平图解Java设计模式
  10. 2019PHP最新简历