Java中字符编码格式详解

 更新时间:2016年03月24日 08:56:00   作者:leesf  
在java应用软件中,会有多处涉及到字符集编码,有些地方需要进行正确的设置,有些地方需要进行一定程度的处理。本文主要给大家讲解java中字符的编码格式等相关问题

一、前言

  在分析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 tostring方法重写代码示例

    java tostring方法重写代码示例

    这篇文章主要介绍了java tostring方法重写代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 在mybatis中去除多余的前缀或者后缀操作

    在mybatis中去除多余的前缀或者后缀操作

    这篇文章主要介绍了在mybatis中去除多余的前缀或者后缀操作。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • SpringBoot集成PDFBox实现电子签章的代码详解

    SpringBoot集成PDFBox实现电子签章的代码详解

    Apache PDFBox 是一个开源的 Java 库,用于处理 PDF 文档,它提供了一系列强大的功能,包括创建、渲染、拆分、合并、加密、解密 PDF 文件,以及从 PDF 中提取文本和元数据等,本文给大家介绍了SpringBoot集成PDFBox实现电子签章,需要的朋友可以参考下
    2024-09-09
  • Java文本编辑器实现方法详解

    Java文本编辑器实现方法详解

    这篇文章主要介绍了Java文本编辑器实现方法,结合实例形式详细分析了java文本编辑器结构、原理、布局、实现步骤与相关操作技巧,需要的朋友可以参考下
    2019-03-03
  • java项目依赖包选择具体实现类示例介绍

    java项目依赖包选择具体实现类示例介绍

    这篇文章主要为大家介绍了java项目依赖包选择具体实现类示例介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • java实现随机生成UUID

    java实现随机生成UUID

    这篇文章主要介绍了java实现随机生成UUID的函数代码,有需要的小伙伴可以参考下。
    2015-07-07
  • IDEA下创建SpringBoot+MyBatis+MySql项目实现动态登录与注册功能

    IDEA下创建SpringBoot+MyBatis+MySql项目实现动态登录与注册功能

    这篇文章主要介绍了IDEA下创建SpringBoot+MyBatis+MySql项目实现动态登录与注册功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • 解读controller层,service层,mapper层,entity层的作用与联系

    解读controller层,service层,mapper层,entity层的作用与联系

    这篇文章主要介绍了关于controller层,service层,mapper层,entity层的作用与联系,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • java-synchronized 嵌套使用代码详解

    java-synchronized 嵌套使用代码详解

    本文以synchronized 的同步造成了死锁为例,介绍了java-synchronized 嵌套使用代码详解,同时对锁和死锁的概念进行了说明,需要的朋友可以了解下。
    2017-09-09
  • java中匿名内部类详解

    java中匿名内部类详解

    这篇文章主要对java中的匿名内部类的详细总结,需要的朋友可以参考下
    2017-04-04

最新评论