Java 字符编码与解码

1、字符编码的发展历程

①、ASCII 码

  因为计算机只认识数字,所以我们在计算机里面的一切数据都是以数字来表示,因为英文字符有限,所以规定使用的字节的最高位是 0,每一个字节都是以 0-127 之间的数字来表示。比如 A 对应 65,a 对应 97。这便是 美国标准信息交换码,ASCII

		String str = new String("Aa");
		byte[] strASCII = str.getBytes("ASCII");
		System.out.println(Arrays.toString(strASCII));//[65, 97]

  ②、GB2312 码

  随着计算机在全球的普及,很多国家和地区都把自己的字符引入了计算机,比如汉字。此时发现一个字节能表示的数字范围太小,不能包含所有的中文汉字。那么就规定使用两个字节来表示一个汉字。

  规定:原有的 ASCII 字符的编码保持不变,仍然使用一个字节表示,为了区别一个中文字符与两个 ASCII 码字符相区别。中文字符的每个字节最高位规定为 1(即中文的二进制是负数),这便是 GB2312 编码

		String str = new String("Aa帅锅");
		byte[] strASCII = str.getBytes("GB2312");
		System.out.println(Arrays.toString(strASCII));//[65, 97, -53, -89, -71, -8]

  ③、GBK

  由于中国汉字太多,在 GB2312 的基础上增加了更多的中文字符,这种编码是 GBK

问题:如果只是在中国,那么大家都认识汉字,但是如果是别的国家,而该国家的码表中是没有收录汉字的。那么计算机在显示的时候就为乱码或是别的字符

解决办法:为了解决各个国家因为本地化字符编码带来的影响,就把全世界所有的字符统一进行编码---Unicode 编码

     此时某一个字符在全世界任何地方显示都是固定的,比如汉字 哥,在任何地方都是以十六进制 54E5 来表示。

     Unicode 的字符编码都占有两个字节

  ④、UTF-8

  是一种针对 Unicode 的可变长度字符编码,又称为 万国码,是 Unicode 的实现方式之一。编码中的第一个字节仍与 ASCII 兼容,这使得原来处理 ASCII 字符的软件无须或只需做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持 UTF-8 编码

		String str = new String("Aa帅锅");
		byte[] strASCII = str.getBytes("UTF-8");
		System.out.println(Arrays.toString(strASCII));//[65, 97, -27, -72, -123, -23, -108, -123]

存储字母、数字:无论什么字符集都占有 1 个字节

存储汉字:GBK 家族占有 2 个字节。UTF-8 占有 3 个字节

       不能使用单字节的字符集(ASCII/ISO-8859-1)来存储中文

2、字符的编码和解码

信息在计算机网络中传输是以字节的形式。那么如何变为字节?这就是编码的过程。那么计算机接收了这个编码,如何让使用者认识呢?那必须要将字节转换为人所识别的字符串形式,这就是解码的过程。

  编码:将字符串转换为 byte 数组

  解码:把 byte 数组转换为 字符串

注意:①、编码格式和解码格式必须一致,否则乱码

String str = new String("Aa帅锅");
		//编码操作
		byte[] strByte = str.getBytes("GBK");
		System.out.println(Arrays.toString(strByte));//[65, 97, -53, -89, -71, -8]
		
		//解码操作  
		//注意编码的字符集和解码的字符集格式必须一致(是其扩展字符集也可以),否则会乱码
		//第一种:编码格式为 GBK,解码格式为 ISO-8859-1  那么就会乱码
		String str2 = new String(strByte,"ISO-8859-1");
		System.out.println(str2); //Aa?§??
		
		//第二种:编码和解码格式一致
		String str3 = new String(strByte,"GBK");
		System.out.println(str3); //Aa帅锅

  ②、有时候编码为和解码格式一致了,但是还是乱码,这是因为在数据在传输过程中经过服务器的处理,而这个服务器可能是外国人编写的,那么就会将数据转换为 别的字符格式,那么你如果还是直接转为自己想要的格式是会乱码的。

  解决办法:先获取经过服务器之后的数据还原编码,然后在进行解码

String str = new String("Aa帅锅");
		//编码操作
		byte[] strByte = str.getBytes("UTF-8");
		System.out.println(Arrays.toString(strByte));//[65, 97, -27, -72, -123, -23, -108, -123]
		
		
		//中间经过了服务器的传输,编码格式转成了 ISO-8859-1
		String str2 = new String(strByte,"ISO-8859-1");
		
		//解码操作  ,此时如果直接进行解码,那么会乱码
		String str3 = new String(str2.getBytes(),"UTF-8");
		System.out.println(str3); //Aa???????
		
		//对于上面的乱码,我们必须先还原服务器之前的编码格式,然后在进行解码。那么就不会乱码
		byte[] strByte2 = str2.getBytes("ISO-8859-1");
		String str4 = new String(strByte2,"UTF-8");
		System.out.println(str4); //Aa帅锅

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

Java8 Lambda表达式.md什么是λ表达式λ表达式的类型λ表达式的使用其它相关概念

为了支持函数式编程,Java 8引入了Lambda表达式. 在Java 8中采用的是内部类来实现Lambda表达式.具体实现代码,可以通过debug看, 同时...

673
来自专栏闵开慧

Java盲点解析

1 堆栈区别     Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarr...

3136
来自专栏Java架构师进阶

Java 已老,Kotlin 或将取而代之?

Java已经成为历史。它无法发展成现代语言,同时保证向后兼容性。但它为我们带来了最好的JVM生态系统,并引导了许多优秀语言的诞生,如Groovy、Scala、C...

603
来自专栏AlgorithmDog的专栏

为了 1% 情形,牺牲 99% 情形下的性能:蜗牛般的 Python 深拷贝

最近使用 Python 一个项目,发现 Python 的深拷贝 copy.deepcopy 实在是太慢了。 ? 相关背景 在 Pytho...

2255
来自专栏开发与安全

从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)

一、boost 智能指针 智能指针是利用RAII(Resource Acquisition Is Initialization:资源获取即初始化)来管理资源。关...

2190
来自专栏崔庆才的专栏

Python 3 中 Redis 的用法

在本节我们介绍一下 Python 的 Redis 操作,在本节开始之前请确保你已经安装好了 Redis 及Python Redis 库。Redis 库提供两个类...

9780
来自专栏java达人

最有价值的50道java面试题(一)

来自骆昊的技术专栏 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象是将一类对象的共同特征总结出来构造类的过程,...

22310
来自专栏女程序员的日常

虚函数&多态

对于经常被问到的虚函数和多态的问题,发现百度百科回答得十分详细,所以自己在百度百科上的解释进行总结 一、虚函数 (1)虚函数简介:在某基类中声明为virtua...

2001
来自专栏个人随笔

深入类的方法

一.C#关键字扩充解释:   1. new :     1)开辟空间     2)调用构造     3)实例化对象   2. this:     当前类的实例,...

2707
来自专栏杨建荣的学习笔记

MySQL数值类型在binlog中需要注意的细节(r12笔记第69天)

MySQL里的数值类型分得很细,光整型数据就有多种数据类型。tinyint,smallint,mediumint,int(integer),还有范围最大...

3017

扫码关注云+社区