简单介绍编码

Unicode:是容纳世界所有文字符号的国标标准编码,使用四个字节为每个字符编码

UTF:是英文 Unicode Transformation Format 的缩写,意为把 Unicode 字符转换为某种格式。UTF系列编码方
案(UTF-8、UTF-16、UTF-32)均是由 Unicode 编码方案衍变而来,以适应不同的数据存储或传递,它们都可以完全
表示 Unicode 标准中的所有字符。目前,这些衍变方案中 UTF-8 被广泛使用,而 UTF-16 和 UTF-32 则很少被使用。

UTF-8 使用一至四个字节为每个字符编码,其中大部分汉字采用三个字节编码,少量不常用汉字采用四个字节编码。
因为 UTF-8 是可变长度的编码方式,相对于 Unicode 编码可以减少存储占用的空间,所以被广泛使用。

UTF-16 使用二或四个字节为每个字符编码,其中大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。
UTF-16 编码有大尾序和小尾序之别,即 UTF-16BE 和 UTF-16LE,在编码前会放置一个 U+FEFF 或 U+FFFE
(UTF-16BE 以 FEFF 代表,UTF-16LE 以 FFFE 代表),其中 U+FEFF 字符在 Unicode 中代表的意义
是 ZERO WIDTH NO-BREAK SPACE,顾名思义,它是个没有宽度也没有断字的空白。

UTF-32 使用四个字节为每个字符编码,使得 UTF-32 占用空间通常会是其它编码的二到四倍。
UTF-32 与 UTF-16 一样有大尾序和小尾序之别,编码前会放置 U+0000FEFF 或 U+0000FFFE 以区分。

乱码的原因

文件要保存在硬盘上就必须要以某种编码方式进行保存,一般都是按照操作系统默认的编码格式进行保存,现在我们
假设要创建一个文件a
1. 打开编辑器
2. 输入中文字符+英文字符。这时字符存储在编辑器所在进程的内存之中(以编辑器自身在内存中存储字符的编码格式
存储字符在内存上,假设在内存中字符以utf-8编码方式保存)
3. 保存到硬盘上。选择格式为gbk,编辑器自动且正确(除非编辑器本身有问题)将内存中utf-8编码的字符转换成gbk
编码保存到硬盘上,字符内容保持不变(无乱码),只是格式换了一下(就像西班牙语的”hello”转换成了希腊语的”hello”)
4. 选择文本浏览工具打开文件a。打开文件时选择读取文件的编码格式为utf-8,这时就出现问题了,以gbk编码保存的文件a
实际上就是”你好,hello”这句话的gbk格式的16进制数字,然后用utf-8读取16进制的方式读取它必然出现乱码(等同于一句西班牙语
你用希腊语的语法去读,肯定都不懂)

综上,出现乱码的原因是:文件保存编码格式和读取编码格式的不匹配造成的

java编码存在两方面内容:JVM之外和JVM之内

JVM之外:java源文件(.java)和编译后的.class文件,源文件可以采用多种编码格式如utf-8(unix linux平台默认)
或者gbk(windows平台默认),当将源码用javac编译的时候,默认是javac按照系统默认的编码格式读取java源文件,
然后以utf-8的格式输出到.class文件中,换句话说,在默认情况下unix平台,javac用utf-8格式读取java源文件
然后以utf-8格式写.class;在默认情况下windows平台,javac用gbk格式读取java源文件然后以utf-8格式写.class

但是如果说源文件的编码格式不采用操作系统默认格式呢?如在windows平台下用utf-8格式保存java源文件(一般ide中
都有选项选择文件保存编码格式),如果不采用ide,直接用javac(javac)编译该源文件,则会造成乱码

/**
* windows 平台下用utf-8保存,同时直接用javac编译
* (不要用ide,ide会智能根据文件编码格式告诉javac用正确的方式便宜)
* 发现乱码
*/
public class Main {public static void main(String[] args) {String a = "中";System.out.println(a);System.out.println(a.toCharArray().length); //1}
}

因此这里的编码转换牵扯到3步 以utf-8保存源文件,以gbk读取源文件,再以utf-8保存.class文件 第二步就出错了等于将utf-8转gbk的乱码以utf-8写,那么必然是乱码,至于如何告诉javac我的原文件是什么编码格式的javac -Dfile.encoding=xxx xx.java 就行了

JVM之内:当运行java字节码时,读入到内存里的字符或者字符串都用charchar[]表示,而char是采用utf-16的
但不是真正的utf-16,为什么这样说? char在java里一直是16位的也就是说只能表示带utf-16的0x0000-0xFFFF(BMP
basic multilingual plane)为止,当对于超过16位的utf-16字符来说(比如表情符号)就需要多个char

public class Main {public static void main(String[] args) {String a = new String(new byte[]{(byte)0xF0, (byte)0x9F, (byte)0x98, (byte)0x81});System.out.println(a);System.out.println(a.toCharArray().length); //2}
}

概括一点说,在JVM中运行时字符串是char[],字符是char 永远的16位,以utf-16(2-4字节)编码但只截取了低16位
截取的结果与unicode(永远的4字节)的低16位同

public class Main {public static void main(String[] args) {String a = "中";System.out.println(a.toCharArray().length); //1System.out.println(Integer.toHexString(a.toCharArray()[0])); //4e2dchar b = '中';System.out.println(Integer.toHexString(b)); //4e2d}
}

此网站查询字符的各种编码值

stackoverflow中的解释
- A Java char takes always 16 bits.
- A Unicode character, when encoded as UTF-16, takes “almost always” (not always) 16 bits: that’s because there are more than 64K unicode characters. Hence, a Java char is NOT a Unicode character (though “almost always” is).
- “Almost always”, above, means the 64K first code points of Unicode, range 0x0000 to 0xFFF (BMP), which take 16 bits in the UTF-16 encoding.
- A non-BMP (“rare”) Unicode character is represented as two Java chars (surrogate representation). This applies also to the literal representation as a string: For example, the character U+20000 is written as “\uD840\uDC00”.
- Corolary: string.length() returns the number of java chars, not of Unicode chars. A string that has just one “rare” unicode character (eg U+20000) would return length() = 2 . Same consideration applies to any method that deals with char-sequences.
- Java has little intelligence for dealing with non-BMP unicode characters as a whole. There are some utility methods that treat characters as code-points, represented as ints eg: Character.isLetter(int ch). Those are the real fully-Unicode methods.

java乱码 java使用的编码是utf-8还是utf-16还是unicode相关推荐

  1. jsp java乱码转换_Java Web 编码问题一:jsp的编码问题

    首先我们来看一张由eclipse生成的jsp文件的头: 图1:JSP文件编码 如上图所示jsp中的三个编码, ①代表的是服务器响应客户端请求的编码方式.服务器会用它来设置http响应头的content ...

  2. java %u解码_Java:编码与乱码问题

    一.为什么要编码? 由于人类的语言太多,因而表示这些语言的符号太多,无法用计算机的一个基本的存储单元----byte来表示,因而必须要经过拆分或一些翻译工作,才能让计算机能理解. byte一个字节即8 ...

  3. Java几种常见的编码方式

    几种常见的编码格式  为什么要编码  不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的 ...

  4. 再谈java乱码:GBK和UTF-8互转尾部乱码问题分析

    一直以为java中任意unicode字符串可以使用任意字符集转为byte[]再转回来只要不抛出异常就不会丢失数据事实证明这是错的. 经过这个实例也明白了为什么 getBytes()需要捕获异常虽然有时 ...

  5. java学习笔记:常见字符编码和编码头BOM

    ANSI (American National Standards Institute,美国国家标准学会) ANSI编码标准是指所有从基本ASCII码基础上发展起来的编码标准, 比如扩展的ASCII码 ...

  6. 字符集乱码 - java

    常见字符集有:ASCII字符集.GB2312字符集.BIG5字符集. GB18030字符集.Unicode字符集等.计算机要准确的处理各种字符集文字,就需要进行字符编码,以便计算机能够识别和存储各种文 ...

  7. JAVA输出带BOM的UTF-8编码的文件

    https://blog.csdn.net/comeonyangzi/article/details/81708134 当从http 的response输出CSV文件的时候,设置为utf8的时候默认是 ...

  8. java udp乱码_【Java】Java UDP 套接字编程乱码问题

    零.发现问题 用Java写了个UDP收发程序,发现中文有问题! package socket; import java.io.IOException; import java.net.Datagram ...

  9. java乱码怎么解决_如何解决java乱码

    如何解决java乱码 同样的java文件,如果使用不用的工具.编译有可能出现乱码,这是为什么呢?以下是小编为大家搜索整理的如何解决java乱码,希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业 ...

最新文章

  1. 学姐分享:在求职路上少走一些弯路
  2. 2、前端环境搭建(19.04.12)
  3. Jquery——hover与toggle
  4. mysql存储过程数组字符串_Mysql通过存储过程分割字符串为数组
  5. 解析AI漫画系统CariGAN:这效果让漫画师颤抖!
  6. 免费html转换成word,如何免费将网页内容转成Word文档
  7. 项目实操总结:拼团活动的设计
  8. 【英语词组】恋恋不忘Day4-2
  9. 副词(Adverb 简称adv.)
  10. 解决svn小乌龟没有绿勾
  11. Leetcode力扣 MySQL数据库 1132 报告的记录II
  12. 如何把excel中的多行数据按行数拆分成多个
  13. 必看:C语言高效学习方法(附经典试题详解)
  14. 在线版区间众数 hzw的代码。。
  15. 关于凸函数求最大值的下标的小讨论(斐波那契优选法/二分法/三分法)
  16. 连接打印服务器显示无合适驱动,Silex DS-510打印服务器驱动(解决DS-510打印机连接问题)V7.2.1 最新版...
  17. java web图书借阅系统
  18. flutter bug【持续更】
  19. 将INRIA数据集改为PascalVOC格式
  20. linux获取u盘厂商名称,根据/proc/partitions获取插入的U盘设备名称

热门文章

  1. html页面怎么设置不能复制粘贴,网页禁止复制粘贴怎么办? 教你6招, 快速搞定
  2. js中window。location.search的用法和作用。
  3. 20年半年总结—默默的活着真是快活极了
  4. IVD首个AI产品进入创新通道,腾讯AI Lab联手迈瑞引领智慧医疗
  5. linux 文件转utf 8,在Linux系统下把文件转换为UTF-8编码
  6. 字节跳动算法一面2-120201106
  7. 选择IT我不曾后悔?希望高人指点迷津
  8. 三层架构编程、DAO层、Entity层、Service层、Controller层
  9. 使用Au进行人声噪声混合
  10. 脑院计算机专业,神经元规模最大的类脑计算机诞生