简单介绍编码

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
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

因此这里的编码转换牵扯到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
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

概括一点说,在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); //1
System.out.println(Integer.toHexString(a.toCharArray()[0])); //4e2d
char b = '中';
System.out.println(Integer.toHexString(b)); //4e2d
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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技能树首页概览137862 人正在系统学习中

[转帖]java乱码 java使用的编码是utf-8还是utf-16还是unicode的更多相关文章

  1. 深度剖析java编码,彻底解决java乱码问题_1

    理解: 1,Java编译器(即编译成class文件时) 用的是unicode字符集. 2,乱码主要是由于不同的字符集相互转换导致的,理论上各个字符的编码规则是不同的,是不能相互转换的,所以根本解决乱码 ...

  2. java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")

    http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...

  3. 深入解析java乱码

    1.什么是编码 ,为什么要编码 先前从没有思考这么深入的问题,觉得一切理所当然,直到有一天java的乱码让我跪了,他不在听我的话,到处是乱码,这次我不打算放过它,我要收拾了它. 大家都知道,文本文件, ...

  4. 深入解析java String中getBytes()的编码问题

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6900536.html Java服务器后台在和Android端App通信时,遇到了两端关于用MD5加密同一包含 ...

  5. java乱码问题处理

    java乱码问题处理 java乱码出现的问题有很多,这里主要解释tomcat,jsp,html,http(get,post请求乱码处理).常见的问题可能是tomcat,http请求乱码问题,对于jsp ...

  6. java文件传输之文件编码和File类的使用

    ---恢复内容开始--- 我们知道,在用户端和服务端之间存在一个数据传输的问题,例如下载个电影.上传个照片.发一条讯息.在这里我们 就说一下文件的传输. 1.文件编码 相信大家小时候玩过积木(没玩过也 ...

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

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

  8. Java基础-二进制以及字符编码简介

    Java基础-二进制以及字符编码简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 想必计算机毕业的小伙伴或是从事IT的技术人员都知道数据存储都是以二进制的数字存储到硬盘的.从事开 ...

  9. Java实现哈夫曼编码和解码

    最近无意中想到关于api返回值加密的问题,譬如我们的api需要返回一些比较敏感或者重要不想让截获者得到的信息,像如果是做原创图文的,文章明文返回的话则有可能被抓包者窃取. 关于请求时加密的方式比较多, ...

  10. Java乱码解决

    简述 乱码是JAVA开发时经常遇到的问题.主要出现在四种情况: 1.         系统接口之间 2.         POST提交数据 3.         GET提交数据和URL路径 4.    ...

随机推荐

  1. Go 语言为什么建议多使用切片,少使用数组?

    大家好,我是 frank,「Golang 语言开发栈」公众号作者. 01 介绍 在 Go 语言中,数组固定长度,切片可变长度:数组和切片都是值传递,因为切片传递的是指针,所以切片也被称为"引 ...

  2. Centos7 Zabbix3.2安装(yum)

    http://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/  #官网下载地址(只包含zabbix的应用包) ftp://47.104.78.123/zabbix/ ...

  3. 十分钟教你在 k8s 中部署一个前后端应用

    转载至我的博客https://www.infrastack.cn ,公众号:架构成长指南 大家好,我是蜗牛哥,好多开发人员,尤其是没接触过 k8s 的人员对如何在k8s中部署一个 前后端应用很模糊,不 ...

  4. 2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在

    2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在 ...

  5. 终于搞懂了Python模块之间的相互引用问题

    摘要:详细讲解了相对路径和绝对路径的引用方法. 在某次运行过程中出现了如下两个报错: 报错1: ModuleNotFoundError: No module named '__main__.src_t ...

  6. 如何利用CANN DVPP进行图片的等比例缩放?

    摘要:介绍如何用昇腾AI处理器上的DVPP单元进行,图像的等比例缩放,保证图像不变形. 本文分享自华为云社区<CANN DVPP进行图片的等比例缩放>,作者:马城林 . 1. 为什么需要进 ...

  7. 政企上云网络适配复杂,看华为云Stack有妙招

    摘要:政企数据中心部署云资源池后,网络架构变得复杂,如何在数据中心内无缝集成云资源池.如何协同云上业务和云下传统业务的互通.如何解决云上业务的安全合规等新问题出现. 本文分享自华为云社区<[华为 ...

  8. 如何精准预测天气?火山引擎ByteHouse与大地量子这么做

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   伴随着气象技术的发展以及城市气象设施的完善,气象监测服务能力在不断提高,实现短期甚至中长期的气象预测成为可能. ...

  9. Excel 查找替换 -- 快速填充

    单元格匹配,这样就不会把 70 的 0 替换成 7零 了 Ctrl + E 快速填充 一列变多行 快速填充 1. 快速拆分数据 一列数据中包含了姓名和手机号码,这时你需要进行数据拆分,快速填充可以实现 ...

  10. selenium 访问无等待

    from selenium.webdriver.common.desired_capabilities import DesiredCapabilities desired_capabilities ...