一、前言

  在分析Comparable和Comparator的时候,分析到了String类的compareTo方法,String底层是用char[]数组来存放元素,在比较的时候是比较的两个字符串的字符,字符用char来存储,此时,突然想到,Java里面的char可以存放中文吗?后来发现是可以的,并且由此也引出了Java中字符的编码格式问题。

二、Java存储格式

  在Java中,如下代码获取了字符'张'的各种编码格式。

import java.io.UnsupportedEncodingException;
public class Test {
public static String getCode(String content, String format) throws UnsupportedEncodingException {
byte[] bytes = content.getBytes(format);
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toHexString(bytes[i] & 0xff).toUpperCase() + " ");
} return sb.toString();
}
public static void main(String[] args) throws UnsupportedEncodingException {
System.out.println("gbk : " + getCode("张", "gbk"));
System.out.println("gb2312 : " + getCode("张", "gb2312"));
System.out.println("iso-8859-1 : " + getCode("张", "iso-8859-1"));
System.out.println("unicode : " + getCode("张", "unicode"));
    System.out.println("utf-16 : " + getCode("张", "utf-16"));
System.out.println("utf-8 : " + getCode("张", "utf-8"));
  }
}

  运行结果:

gbk : D5 C5
gb2312 : D5 C5
iso-8859-1 : 3F
unicode : FE FF 5F 20
utf-16 : FE FF 5F 20
utf-8 : E5 BC A0

  说明:从结果我们可以知道,字符'张'的gbk与gb2312编码是相同的,unicode与utf-16编码时相同的,但是其iso-8859-1、unicode、utf-8编码都是不相同的,至于各个编码的含义,我们这里不给出解释,下一篇会给出答案。那么,在JVM中,字符'张'是按照哪种编码格式进行存储的呢?下面开始我们的分析。

三、探秘思路

 1. 查看.class文件常量池的存储格式

  测试代码如下  

public class Test {
public static void main(String[] args) {
String str = "张";
}
}

  使用javap -verbose Test.class进行反编译,发现常量池情况如下:

  再使用winhex打开class文件,发现字符'张'在常量池的存储如下

  说明:上面两张可以在class文件中是以utf-8的格式存储的。

  但是在运行时是否是utf-8格式呢?继续我们的探秘之旅。

  2. 在程序中一探究竟

  使用如下代码 

public class Test {
public static void main(String[] args) {
String str = "张";
System.out.println(Integer.toHexString(str.codePointAt(0)).toUpperCase());
}
}

  运行结果:

  5F20

  说明:根据结果我们知道在运行时JVM是使用的utf-16格式进行存储,utf-16一般是使用2个字节进行存储,如果遇到两个字节无法表示的字符则会使用4个字节表示。之后会另外有篇幅进行介绍,并且我们查看Character类源码时,会发现就是使用的utf-16进行编码的,从两面都找到了我们想要的答案。

  3. char类型可以存放中文吗?

  根据上面的探索我们已经知道了Java的class文件中字符是以utf-8进行编码的,在JVM运行时则是以utf-16进行编码存储的。而字符'张'可以用两个字节来表示,而char在Java中也是两个字节,故可以存放。

四、总结

  经过上面的分析,我们知道:

  1. 字符在class文件中是以utf-8格式进行编码的,而在JVM运行时是采用utf-16格式进行编码的。

  2. char类型是两个字节,可以用来存放中文。

  在此次调用的过程中又查阅了好多关于字符方面的资料,受益匪浅,并且发现特别有意思,接下来会进行分享,所以特此预告下一篇将会进一步来介绍编码以及编码在Java中的问题。敬请期待,也谢谢各位园友的观看~

 

【字符编码】Java编码格式探秘的更多相关文章

  1. Java IO4:字符编码

    前言 字符编码,这本不属于IO的内容,但字节流之后写的应该是字符流,既然是字符流,那就涉及一个"字符编码的"问题,考虑到字符编码不仅仅是在IO这块,Java中很多场景都涉及到这个概 ...

  2. 【字符编码】Java字符编码详细解答及问题探讨

    一.前言 继上一篇写完字节编码内容后,现在分析在Java中各字符编码的问题,并且由这个问题,也引出了一个更有意思的问题,笔者也还没有找到这个问题的答案.也希望各位园友指点指点. 二.Java字符编码 ...

  3. 字符编码介绍及java中的应用

    字符编码,就是对日常的控制符号.文字和常用符号的二进制表示.为了准确的表示如何编号,怎么生产八位字节流,Unicode Technical Report (UTR) #17提出现代编码模型的5个层次: ...

  4. 由String的构造方法引申出来的java字符编码

    在String类的constructors中,有一个constructor是将int数组类型转化为字符串: int[] num = {48,49,50,51,52}; String numStr = ...

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

    我们最初学习计算机的时候,都学过ASCII编码. 但是为了表示各种各样的语言,在计算机技术的发展过程中,逐渐出现了很多不同标准的编码格式, 重要的有Unicode.UTF.ISO-8859-1和中国人 ...

  6. Java 字符编码(一)Unicode 字符编码

    Java 字符编码(一)Unicode 字符编码 Unicode(http://www.unicode.org/versions/#TUS_Latest_Version) 是一个编码方案,说白了希望给 ...

  7. Java中char和String 的深入理解 - 字符编码

    开篇 https://blog.csdn.net/weixin_37703598/article/details/80679376 我们并不是在写代码,我们只是将自己的思想通过代码表达出来! 1 将思 ...

  8. Java基础——字符编码

    一.ASII 美国(国家)信息交换标准(代)码. 计算机中只有数字,一切都是用数字表示,屏幕上显示的一个一个的字符也不例外. 一个字节可表示的数字为0-255,足以显示键盘上的所有的字符 例如. a ...

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

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

随机推荐

  1. canvas生成图片并保存到本地文件夹主要代码

    js var url = canvas.toDataURL();//把canvas中的图片变成data:image C# string filepath = ""; string ...

  2. 用javascript实现一个2048游戏

    早就想自己写一个2048游戏了,昨晚闲着没事,终于写了一个 如下图,按方向键开始玩吧. 如果觉得操作不方便,请直接打开链接玩吧: http://gujianbo.1kapp.com/2048/2048 ...

  3. C++ 控制台代码输出控制

    在C++控制台应用程序中可以控制控制台输出的字体颜色和 接受任意按键退出 #ifndef CONSOLE_UTILS_H #define CONSOLE_UTILS_H #include <wi ...

  4. FFT时域与频域的关系,以及采样速率与采样点的影响

    首先对于FFT来说,输入的信号是一个按一定采样频率获得的信号序列,而输出是每个采样点对应的频率的幅度(能量). 下面详细分析: 在FFT的输出数据中,第一个值是直流分量的振幅(这样对应周期有无穷的可能 ...

  5. ABP理论学习之验证DTO

    返回总目录 本篇目录 验证介绍 使用数据注解 自定义验证 标准化 验证介绍 首先应该验证应用的输入.用户或者其它应用都可以向该应用发送输入.在一个web应用中,验证通常要实现两次:在客户端和服务器端. ...

  6. 表格搞定 Asp.net Web 状态管理

    最近在网上搜罗了 ASP.NET WEB 状态管理方面的一些内容,终于把这些内容整合总结了一下. 1. 希望自己通过整理,能够掌握一些,为自己投资. 2. 以便自己忘记,又要浪费时间搜罗. 3. 希望 ...

  7. 模糊测试(fuzz testing)介绍(一)

    模糊测试(fuzz testing)是一类安全性测试的方法.说起安全性测试,大部分人头脑中浮现出的可能是一个标准的“黑客”场景:某个不修边幅.脸色苍白的年轻人,坐在黑暗的房间中,正在熟练地使用各种工具 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (8) -----第二章 实体数据建模基础之继承关系映射TPT

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 2-8 Table per Type Inheritance 建模 问题 你有这样一 ...

  9. Android笔记——permission权限大全

    访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permiss ...

  10. SQLSERVER中的假脱机spool

    SQLSERVER中的假脱机spool 我发现网上对于假脱机的解释都非常零散,究竟假脱机是什么? 这几天在家里研究了一下,收集了很多网上的资料 假脱机是中文的翻译,而英文的名字叫做 spool 在徐老 ...