深入解析java乱码

1.什么是编码 ,为什么要编码

先前从没有思考这么深入的问题,认为一切理所当然,知道有一天java的乱码让我跪了,他不在听我的话,到处是乱码,这次我不打算放过它,我要收拾了它。

大家都知道,文本文件,存储在硬盘上,都是一串二进制  ,01的组合,它本身是不携带任何,哪怕一丁点,信息告诉文本编辑器 hi哥们儿,我是GBK编码,我是UTF-8编

码,我是。。。。。。。

它非常简单,就是01的组合,他不知道自己是什么,所以我们只有知道他是什么然后才能正确的编辑合适用它,首先看个小例子。

这是一个文本文件,他的二进制形式就是一串01

当我我用的终端的编码是GBK显示时(第一次)

当我用UTF-8时(第二次)

他就是这么简单 有是这么无常,很幸运,这一串01无论是在GBK编码,还是在UTF-8中都是有效字符也就是说按UTF-8的编码规则它代表

”汉“   而如果按照GBK编码规则来解析呢他又是    ” 姹 “  ,这就是根源了,编码和解码用的不是一种码。所以大多数情况下你都搞不懂 好端端的文档怎么就乱了码。 这就是需

要编码的原因了。 二进制文件一串01电脑认得但是对他来说就是01没有意义。所以要把它翻译成大家能识别的东西。一种编码编码在我看来就是一种映射, 也就是向刚才所说

的GBK环

境下 它映射成一种东西,UTF-8,环境下它映射成另一种东西,但是本质他俩有是一个东西,那客官又问了 ,明明再UTF-8和GBK环境下都一样,比如说a,这就说的到了,编

码与编码之间的兼容问题了,

想探索的朋友自己可以探索下,各个编码的规则及兼容性,这里就不多说了。

2. 上手编码

写java文件,就先来个helloworld

这是同一个文件 我在不同编码环境下查看,看到的东西是不一样的我的系统是Ubuntu 12.04 默认编码UTF-8  但是提前声明,我这个文件可是GBK编码的所以以GBK形式的编

码查看才有意义,张三 又立了功,下边来编译我的这个HelloWorld 文件,看看有什吗奇迹?

我去,不活啦 helloWorld 都搞不定,这都能出错,这日子没法过了。不过别着急,看错误, 这个字符(当然这里不是张三代表的字符找不到,而是再GBK里代表张三的0101

二进制串在UTF-8里找不到映射所以它没法解析,大家可以了解一下UTF-8的编码规则)UTF-8里找不着,没错  找不着就对了,你不是一次编译到处运行吗?编译都过不去怎么

搞,别着急 javac 里有一个参数,-encoding <encoding>       Specify character encoding used by source files  也就是说你告诉javac 你这个java源文件是什么样的编码,你别给

搞错了,你要是搞错了,幸运的,编译不过去告诉你哪里有问题,要是不幸的      汉  就变成了    姹 啦 想想就可怕   所以不报错并不代表程序没有问题 ,不信你试试,我刚才说

过,我的系统默认是UTF-8 所以没有编译过去这个是GBK编码的源文件,大多数人用的还是windows,而且又安装了中文语言包,所以默认编码大都GBK所以也就能够正常编译

GBK编码的源文件,所以一般没有问题,但大多数程序最终上线运行的环境可是linux啊 ,所有大家设置虚拟机参数是-Dfile.encoding=GBK 这个是谁也不敢偷懒的。

(不过这里说这个还有点早)

当我加上这个参数 编译顺利通过。

感觉到很神圣,运行我的helloWord

UTF-8环境下为

好兴奋啊  终于出来了

GBK环境下运行(这是大多数产生乱码的原因)

这不科学,怎么又乱了 神啊

大家肯定没有忘 java的class文件是什么编码的啊 Unicode对吧 所以张三这个字符串 所以编译完了 ,他就不是GBK了 所有的不管是什么编码的源文件,变成class文件编码都一样,

所以我老老实实的加上了 (这个环境仍然是GBK)

System.out中的这个out是什么?PrintStream  是个流啊  这个流你打算以什么编码来展示它,GBK环境下肯定是以GBK的形式展示吧,可是第一次是乱码为什么,JVM是这样想

得,我有一个Unicode编码的张三在这里,我在说一下我的系统UTF-8在我没告诉JVM以什么编码规则编码时,它肯定使用UTF-8来编 你就会得到一个输入流 这个输入流是一串

00111二进制代表UTF-8下的张三,而到了输出到屏幕这里 屏幕不吃这一套 这一串00001111不代表张三,代表上边的那三个我也不太认识的字(汗颜啊),所以咱得告诉虚拟

机,我要的张三是GBK编码的张三,我要的一串二进制对应GBK里的张三,所以加上个这个就好了。先写到这里吧!再晚赶不上二路汽车了。

下次再写个关于IO的编码的那个我感觉比这个简单点。(配合学习java的一些和编码相关的类效果更加)

先写到这里 ,祝大家 国庆节玩好。不要忘了 撸两行代码 怡怡情,因为几天不见,她没准就把你忘了。

时间: 2024-10-13 17:45:19

深入解析java乱码的相关文章

Atitit 表达式原理 语法分析&#160;原理与实践 解析java的dsl &#160;递归下降是现阶段主流的语法分析方法

Atitit 表达式原理 语法分析 原理与实践 解析java的dsl  递归下降是现阶段主流的语法分析方法 于是我们可以把上面的语法改写成如下形式:1 合并前缀1 语法分析有自上而下和自下而上两种分析方法2 递归下降是现阶段主流的语法分析方法,2 于是我们可以把上面的语法改写成如下形式: 1)       Operator="+" | "-" | "*" | "/" 2)       Expression=<数字>

解析java树形结构

思路一: 1.准备表结构及对应的表数据a.表结构: create table TB_TREE ( CID NUMBER not null, CNAME VARCHAR2(50), PID NUMBER //父节点 ) b.表数据: insert into tb_tree (CID, CNAME, PID) values (1, '中国', 0); insert into tb_tree (CID, CNAME, PID) values (2, '北京市', 1); insert into tb_

Mac 下 Terminal 中 Java乱码的解决方法

在 .bash_profile 中增加一行 export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 就可以了. Mac 下 Terminal 中 Java乱码的解决方法,布布扣,bubuko.com

Java乱码总结

1. http请求是以ISO-8859-1的编码来传送url的 如果页面的content-type为utf-8,那么在发送请求时,会将字符转成utf-8后进行传送 如: 中 的UTF-8编码为:E4 B8 AD在请求时为%E4%B8%AD字节之间是%分隔 那么服务器收到这段字节流后,必须将它转成相应的字符,平时所使用的request.getParameter("name")直接得到了字符串, 那么从字节流到字符流这个过程系统己经帮助我们完成了(乱码的产生由此开始) new String

聊聊高并发(二十五)解析java.util.concurrent各个组件(七) 理解Semaphore

前几篇分析了一下AQS的原理和实现.这篇拿Semaphore信号量做样例看看AQS实际是怎样使用的. Semaphore表示了一种能够同一时候有多个线程进入临界区的同步器,它维护了一个状态表示可用的票据,仅仅有拿到了票据的线程尽能够进入临界区,否则就等待.直到获得释放出的票据. Semaphore经常使用在资源池中来管理资源.当状态仅仅有1个0两个值时,它退化成了一个相互排斥的同步器.类似锁. 以下来看看Semaphore的代码. 它维护了一个内部类Sync来继承AQS,定制tryXXX方法来使

java assert的使用并深入解析Java的assertion

java assert的使用并深入解析Java的assertion 分类: java2012-12-05 13:32 2020人阅读 评论(0) 收藏 举报 原文出处:http://blog.csdn.net/wguoyong/article/details/6909828.谢谢作者. assert expression1;assert expression1:expression2;如果expression1为true,则不抛出错误,程序正常运行,expression2也不会执行.如果expr

聊聊高并发(四十一)解析java.util.concurrent各个组件(十七) 任务的异步执行和状态控制

聊聊高并发(三十九)解析java.util.concurrent各个组件(十五) 理解ExecutorService接口的设计这篇说了ExecutorService接口扩展了Executor接口,在执行任务的基础上,提供了执行框架生命周期的管理,任务的异步执行,批量任务的执行的能力.AbstractExecutorService抽象类实现了ExecutorService接口,提供了任务异步执行和批量执行的默认实现.这篇说说任务的异步执行和状态控制 说明一点,使用Executor框架执行任务的方式

深入解析Java设计模式之动态代理

深入解析Java设计模式之动态代理 代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替"实际"对象的对象.这些操作通常涉及与"实际"对象的通信,因此代理通常充当着中间人的角色,下面是一个用来展示动态代理结构的简单示例: /** 普通(非动态)代理示例: */ interface Interface { void doSomething(); void somethingElse(String arg); } class RealObject

聊聊高并发(二十九)解析java.util.concurrent各个组件(十一) 再看看ReentrantReadWriteLock可重入读-写锁

上一篇聊聊高并发(二十八)解析java.util.concurrent各个组件(十) 理解ReentrantReadWriteLock可重入读-写锁 讲了可重入读写锁的基本情况和主要的方法,显示了如何实现的锁降级.但是下面几个问题没说清楚,这篇补充一下 1. 释放锁时的优先级问题,是让写锁先获得还是先让读锁先获得 2. 是否允许读线程插队 3. 是否允许写线程插队,因为读写锁一般用在大量读,少量写的情况,如果写线程没有优先级,那么可能造成写线程的饥饿 关于释放锁后是让写锁先获得还是让读锁先获得,