1.编码是什么?
信息在计算机中的存储形式为二进制,但我们在自然界中则是各国家不同的文字体系。将自然界中的问题体系翻译成机器可以识别的信息的过程就称为编码。
2.有哪些常见的字符集?
ASCII、GB**、Unicode
3.UTF-8不是字符集吗?
UTF-8不是字符集,是UNICODE的一种编码方式,是一套以 8 位为一个编码单位的可变长编码
4.为什么不统一用同一套字符集?
ASCII码
最早出现的ASCII码,每个字或符号占用个字符,除第一个字节默认为0(做奇偶数校验用),ASCII码总共能表示个值,包括数字、大写字母、小写字母、常用标点符号等。下图为ASCII码对应图。

随着计算机的迅速发展,127个字符已经无法满足各个国家的语言在计算机中的使用。GBK字符集即是为了满足汉字在计算机中的使用而产生。
GBK字符集
GBK编码中小于127的单字节仍能表示ASCII码中的所有字符,而连续两个大于127的字符则可以用来表示一个汉字。GBK字符集(含7000多个汉字)中也用两个字符表示了ASCII字符集中所有的字符。由两个字节表示的ASCII中的字符为全角字符,单字节表示的ASCII码中的字符为半角字符。
各个国家为了适应本国的语言和字符都会涉及一套类似GBK一样的字符编码集。由于没有统一编码规则,因此相同的二进制编码会被表示为不同语言文字。为了解决不同文字体系的兼容问题,Unicode(万国码)应运而生
Unicode
Unicode由两个字节组成,包括世界上所有的文字。单Unicode在制定过程中并未考虑兼容其他任何一个字符编码集。 Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。
如果一个文本文件的头两个字节是FE FF,就表示该文件采用大头方式;如果头两个字节是FF FE,就表示该文件采用小头方式。
UTF-8
UTF-8是Unicode的实现方式之一
UTF-8是一种针对Unicode的可变长字符编码,使用1~4个字节表示的编码方式。它可以用来表示Unicode中的任何一个字符。长度为一个字节时同时能兼容ASCII码。
编码规则如下:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
| Unicode | UTF-8 |
|---|---|
| 0000 ~007F | 0XXX XXXX |
| 0080 ~07FF | 110X XXXX 10XX XXXX |
| 0800 ~FFFF | 1110XXXX 10XX XXXX 10XX XXXX |
| 1 0000 ~1F FFFF | 1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX |
| 20 0000 ~3FF FFFF | 1111 10XX 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX |
| 400 0000 ~7FFF FFFF | 1111 110X 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX 10XX XXXX |
以汉字"严"为例,演示如何实现UTF-8编码[3]。
已知"严"的unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此"严"的UTF-8编码需要三个字节,即格式是"1110xxxx 10xxxxxx 10xxxxxx"。然后,从"严"的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,"严"的UTF-8编码是"11100100 10111000 10100101",转换成十六进制就是E4B8A5。
5.java编码转换过程
1)使用编辑器编写java源文件,文件保存时会采用操作系统的默认编码格式(中文系统一般为GBK)。
2)使用javac编译源文件,JDK首先会确认它的编译参数encoding来确定源代码字符集,如果我们不指定该编译参数,JDK首先会采用操作系统的默认编码格式,然后JDK会将源文件从文件的编码格式转化为JAVA内部默认的UNICODE格式放入内存中。
3)运行.class文件,存在以下三种情况:
-console直接运行
-jsp/servlent类
-java与数据库之间
(如果是JSP文件,WEB容器首先会调用JSP编译器会检索JSP文件中是否设定编码格式,如果没有找到则调用JDK采用默认的编码格式将JSP文件转换为Servlet类)
console直接运行

jsp/servlent类

java与数据库之间

参考文献
java中文乱码解决之道(三)-----编码详情:伟大的创想---Unicode编码
UNICODE,GBK,UTF-8区别