目录

一、引言

二、基础知识介绍

三、java中的编码问题

1、字符转内存

2、编码转换,内存转字符

四、总结


一、引言

字符编码一直是萦绕在心头的痛,精华其实在如何编码上,但是由于平台、编码错乱、各种水文章的原因,导致一直在摸索中前进,以为认为的是对的,直到下次碰到问题才能更深一步理解,在这里碰到的问题总算差不多了,稍微总结一下以免后人栽倒坑里==

二、基础知识介绍

首先要了解的是字符集与字符编码的关系:

字符集就相当于汉语、英语、西班牙语等语种,其中确定了包含的文字和文字对应的编号;

字符编码指的是如何将这些文字对应的编号进行加工按照一定的法则排列;

字符集:

因为计算机美国人发明的,最早的字符集是ASCII字符集,然后欧洲人开始拓展了ASCII字符集为ISO8859-1,其中包含了西班牙语等一些字母;

后来计算机开始支持汉语,汉语也有了自己的字符集GB2312,由于汉字实在太多了,后来拓展为GBK字符集,两者相互兼容;

由于各个国家有各个国家(咯咯咯咯咯咯咯)的字符集,有些编号相同但是不同字符集对应的翻译的不同,瞎举例子0001在ascii字符集对应“s”,在GBK字符集对应的是“我”,开始搞了全球通用的一套编码unicode;

字符编码:

每一套字符集中都对应一种或者多种字符编码,

ASCII字符集——ASCII编码;ISO-8859-1字符集——ISO8859-1编码;

GB2312字符集——GB2312编码;GBK字符集——GBK编码;

Unicode字符集——UTF-16/UTF-8/UTF-32;

三、java中的编码问题

1、字符转内存

java中的基本类型byte、short、int、long;float、double;bool;char中,涉及到字符的是char和byte;

引用类型中主要是String,底层是char保存(jdk8以后的是byte保存);

       String s = "君山";char[] charsutf=s.toCharArray();System.out.print("toCharArray:");for (char temp:charsutf) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();System.out.print("iso8859-1:");byte[] iso = s.getBytes("iso8859-1");//System.out.println(gbks.toString());for (byte temp:iso) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();System.out.print("GB2312:");byte[] iso2312 = s.getBytes("GB2312");//System.out.println(gbks.toString());for (byte temp:iso2312) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();System.out.print("gbk:");byte[] gbks = s.getBytes("GBK");//System.out.println(gbks.toString());for (byte temp:gbks) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();System.out.print("utf-8:");byte[] byteutf= s.getBytes("utf-8");for (byte temp:byteutf) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();System.out.print("utf-16:");byte[] byteutf16= s.getBytes("utf-16");for (byte temp:byteutf16) {System.out.print(Integer.toHexString(temp)+",");}

结果:

toCharArray:541b,5c71,
iso8859-1:3f,3f,
GB2312:ffffffbe,fffffffd,ffffffc9,ffffffbd,
gbk:ffffffbe,fffffffd,ffffffc9,ffffffbd,
utf-8:ffffffe5,ffffff90,ffffff9b,ffffffe5,ffffffb1,ffffffb1,
utf-16:fffffffe,ffffffff,54,1b,5c,71,

我们来一个个解释:

首先,541b,5c71怎么来的?这个是java自己内部的机制,java会自动把String字符串内部解析为char[],每个char中的值如何确定的呢?是根据Unicode字符集确定的,unicode中“君”对应541b,“山”对应5c71;

那现在我们确定知道了java内部的存储字符集了,是unicode,当转换字符集(字符编码)的时候是怎么做的呢?先跳过两个,看gbk和utf-8,得到了一堆ffffff+十六进制的数字

“君山”两个字的GBK编码为BEFD、C9BD,对应我们的输出结果比较相似,把前面的ffffff去掉就是;

“君山”两个字的Unicode编码为541B、5C71,(这个正好对应了上一个unicode解释);

这里可以看到utf-8编码相似,去掉前面的ffffff就是结果;

其他的字符编码iso8859-1,GB2312、utf-16等都是类似的。

总结一下这里我们探讨的问题

  • java内部字符存储字符集与字符编码;
  • java中String.getByte(“charsetname”)获取的是不是和我们理解的字符集一致,结果是,使用这个最实质上是转换的字符集;

2、编码转换,内存转字符

首先说明下java中编码解码过程(以utf-8编码,gbk解码为例说明)

对应代码如下(注释//之间的部分为上述过程对应代码,其他代码为实验使用):

   String s = "君山";char[] charsutf=s.toCharArray();System.out.print("toCharArray:");for (char temp:charsutf) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();System.out.print("iso8859-1:");byte[] iso = s.getBytes("iso8859-1");//System.out.println(gbks.toString());for (byte temp:iso) {System.out.print(Integer.toHexString(temp)+",");}String sss=new String(iso,"utf-8");System.out.println("+"+sss);System.out.println();System.out.print("GB2312:");byte[] iso2312 = s.getBytes("GB2312");//System.out.println(gbks.toString());for (byte temp:iso2312) {System.out.print(Integer.toHexString(temp)+",");}sss=new String(iso2312,"GB2312");System.out.println("+"+sss);System.out.println();System.out.print("gbk:");byte[] gbks = s.getBytes("GBK");//System.out.println(gbks.toString());for (byte temp:gbks) {System.out.print(Integer.toHexString(temp)+",");}sss=new String(gbks,"GBK");System.out.println("+"+sss);/System.out.println();System.out.print("utf-8:");byte[] byteutf= s.getBytes("utf-8");for (byte temp:byteutf) {System.out.print(Integer.toHexString(temp)+",");}sss=new String(byteutf,"gbk");System.out.println("+"+sss);char[] chargbk=sss.toCharArray();System.out.print("toCharArray:");for (char temp:chargbk) {System.out.print(Integer.toHexString(temp)+",");}System.out.println();byte[] bbbb=toBytes("e590");System.out.println(new String(bbbb,"gbk"));System.out.println();System.out.print("utf-16:");byte[] byteutf16= s.getBytes("utf-16");for (byte temp:byteutf16) {System.out.print(Integer.toHexString(temp)+",");}sss=new String(byteutf16,"utf-16");System.out.println("+"+sss);

结果:

toCharArray:541b,5c71,
iso8859-1:3f,3f,+??GB2312:ffffffbe,fffffffd,ffffffc9,ffffffbd,+君山gbk:ffffffbe,fffffffd,ffffffc9,ffffffbd,+君山utf-8:ffffffe5,ffffff90,ffffff9b,ffffffe5,ffffffb1,ffffffb1,+鍚涘北
toCharArray:935a,6d98,5317,
鍚utf-16:fffffffe,ffffffff,54,1b,5c,71,+君山

在第一小节中我们知道了字符串在内存中的保存形式是char[],编码字符集为unicode,但是当java在编码转换的时候是怎么做的呢,这里以“君山”从utf-8转为gbk为例进行说明。

  • 当我们新建String数组“君山”;
  • 内存中char[]就以Unicode的形式保存了数组,为{541b,5c71};
  • 获取utf-8编码的byte[],将Unicode进行utf-8编码(一般一个汉字对应三个byte),存储格式为{e5,90,9b,e5,b1,b1},逻辑上为{e5909b,e5b1b1};
  • 将byte[]使用gbk解码(一般两个byte转为一个汉字)字符集转换但是byte数组存储并没有改变,存储格式为{e5,90,9b,e5,b1,b1},逻辑上为{e590,9be5,b1b1};
  • 内存中byte[]转换为char[],以unicode字符集保存,为{935a,6d98,5317};
  • 显示“鍚涘北”;

四、总结

  • 字符集、字符编码;
  • 内存中的字符unicode;
  • 字符集转换unicode转utf-8,utf-8转gbk,gbk转Unicode;

Java——字符编码详细解释相关推荐

  1. Java字符编码知识简介

    1.基本信息 摘要:在Java应用程序特别是Web应用中,经常遇到字符的编码问题.为了防止出现乱码,首先需要了解字符编码的基本概念以及Java是如何处理字符编码的,这样就可以有目的地在输入/输出环节中 ...

  2. 【JAVA编码专题】JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  3. 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题

    这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...

  4. 【JAVA编码】 JAVA字符编码系列二:Unicode,ISO-8859,GBK,UTF-8编码及相互转换

    http://blog.csdn.net/qinysong/article/details/1179489 这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记 ...

  5. java字符编码方式总结

    java字符编码方式总结一.概要在JAVA应用程序特别是基于WEB的程序中,经常遇到字符的编码问题.为了防止出现乱码,首先需要了解JAVA是如何处理字符的,这样就可以有目的地在输入/输出环节中增加必要 ...

  6. 关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换

    出处: https://www.cnblogs.com/haimishasha/p/6117968.html 目录 1.1. ISO-8859-1 通常叫做Latin-1 1.2. GB2312/GB ...

  7. Java字符编码详解

    char "字节"是byte,"位"是bit : 1 byte = 8 bit : char 在Java中是2个字节.java采用unicode(<jav ...

  8. Java字符编码根本原理

    2019独角兽企业重金招聘Python工程师标准>>> Java开发中,常常会遇到乱码的问题,一旦遇到这种问题,常常就很扯蛋,每个人都不愿意承认是自己的代码有问题.其实编码问题并没有 ...

  9. Java字符编码介绍

    在计算机中,任何的文字都是以指定的编码方式存在的,在 Java 程序的开发中最常见的是 ISO8859-1.GBK/GB2312.Unicode. UTF 编码. Java 中常见编码说明如下: IS ...

最新文章

  1. 第六届数学、计算机与生命科学交叉研究青年学者论坛 (大牛云集的生信会议,免注册费且提供午餐)...
  2. MySQL数据库提升篇-----触发器
  3. Java: 复制文件最快、高效率的方法
  4. mac java jdk_mac下java JDK的下载安装和配置
  5. J2EE与.NET技术架构的比较
  6. 容器源码分析之LinkedList(三)
  7. android .9图片如何引用,Android调用相机拍照并返回路径和调用系统图库选择图片...
  8. NMOS PMOS Charge pump flying capacitor充电泵
  9. 小梅哥Xilinx FPGA学习笔记10——串口通信发送
  10. self paced learning(自步学习)
  11. 服务器系统如何克隆,服务器如何克隆操作系统
  12. 阿里ET大脑如何帮助养猪产业提升PSY从20到32?
  13. 分享5款超级实用的电脑软件
  14. 守得住孤独,把得住清欢
  15. seata源码解析:TM RM 客户端的初始化过程
  16. python 学习分享之简单的播放音乐1(playsound)
  17. discuzx update sitekey.php,Discuz如何清除应用中心密码附加工具
  18. 全球与中国贵金属电子废料回收市场动态调研与未来需求趋势预测报告2021年版
  19. 图像迁移风格保存模型_一种图像风格迁移方法与流程
  20. C++把一个字符转换成string方法

热门文章

  1. 综合案例-注册页面(HTML)
  2. 测试所有类型的Class
  3. 一些常用的简单的Lambda写法
  4. git之配置在Terminal显示git分支
  5. java doget 返回json_HttpClient调用doGet、doPost、JSON传参及获得返回值
  6. 计算机页面高度怎么设置方法,win10系统调节任务栏高度的设置技巧
  7. 基于SDN的环路通信
  8. MySQL——优化ORDER BY语句
  9. 判断页面环境是否在小程序的webview中
  10. DevExpress v17.2新版亮点——XAF篇