• 关于Java中编码集的有趣现象和解释


    这是在整理另一篇博客的时候发现的一个有趣的现象,是这样描述的:我们都知道Java默认使用的是UniCode编码集,我们也知道char类型占用两个字节。所以奇怪的现象又发生了(见代码):

     1     @Test
     2     public void testCode_1() throws Exception{
     3 
     4         System.out.println("汉字UniCode编码大小:" + "字".getBytes("UniCode").length);
     5         System.out.println("数字UniCode编码大小:" + "0".getBytes("UniCode").length);
     6         System.out.println("字母UniCode编码大小:" + "a".getBytes("UniCode").length);
     7         System.out.println("=========================================");
     8 
     9         System.out.println("汉字GBK编码大小:" + "字".getBytes("GBK").length);
    10         System.out.println("数字GBK编码大小:" + "0".getBytes("GBK").length);
    11         System.out.println("字母GBK编码大小:" + "a".getBytes("GBK").length);
    12         System.out.println("=========================================");
    13 
    14         System.out.println("汉字GB2312编码大小:" + "字".getBytes("GB2312").length);
    15         System.out.println("数字GB2312编码大小:" + "0".getBytes("GB2312").length);
    16         System.out.println("字母GB2312编码大小:" + "a".getBytes("GB2312").length);
    17         System.out.println("=========================================");
    18 
    19         System.out.println("汉字UTF-8编码大小:" + "字".getBytes("UTF-8").length);
    20         System.out.println("数字UTF-8编码大小:" + "0".getBytes("UTF-8").length);
    21         System.out.println("字母UTF-8编码大小:" + "a".getBytes("UTF-8").length);
    22         System.out.println("=========================================");
    23 
    24         System.out.println("汉字UTF-16编码大小:" + "字".getBytes("UTF-16").length);
    25         System.out.println("数字UTF-16编码大小:" + "0".getBytes("UTF-16").length);
    26         System.out.println("字母UTF-16编码大小:" + "a".getBytes("UTF-16").length);
    27         System.out.println("=========================================");
    28 
    29     }

    testCode_1执行的结果如下:

    汉字UniCode编码大小:4
    数字UniCode编码大小:4
    字母UniCode编码大小:4
    =========================================
    汉字GBK编码大小:2
    数字GBK编码大小:1
    字母GBK编码大小:1
    =========================================
    汉字GB2312编码大小:2
    数字GB2312编码大小:1
    字母GB2312编码大小:1
    =========================================
    汉字UTF-8编码大小:3
    数字UTF-8编码大小:1
    字母UTF-8编码大小:1
    =========================================
    汉字UTF-16编码大小:4
    数字UTF-16编码大小:4
    字母UTF-16编码大小:4
    =========================================

    发现其实Unicode编码的大小和UFT-16的大小是一样的统一是4个字节,而GBK和GB2312是一样的分别是(汉字2个字节,数字1个字节,字母1个字节)。但这其实没什么奇怪的。接下来的事情才令人不可理解:

    1     @Test
    2     public void testCode_2(){
    3         char c = (char)Long.MAX_VALUE;
    4         System.out.println("char类型的大小:"+(int)c);
    5     }

    testCode_2执行的结果如下:

    char类型的大小:65535

    可能你还没觉得这个结果奇怪。我们都知道计算机都是使用二进制存储,65535是2^16-1,也就是说char用了2个字节,但是UniCode是4个字节啊,4个字节应该是2^32-1=4294967295。这下应该明白是不是哪里不对?颠覆了自己的认知?怀疑自己记错了?可能都开怀疑java可能不是用UniCode编码的,但是无论如何也不会用GBK或者GB2312编码的,因为这两个编码是我们中国搞的,JDK不是我们中国搞的,所以通用的话肯定是UniCode编码了。

    过于这个问题的理解:我们知道编码是有发展过程的,这个故事说起来就很长远了,我们找重点。简单来说,就是曾经UniCode编码是占两个字节的时候,我们使用的JDK就采用了这种编码。后来人家UniCode扩展了更多的内容变成了4个字节,但是我们JDK没有扩展,在JDK1.5的时候并没有扩展,并保留了char类型的行为来表示UTF-16,并实现了码位的概念来表示UTF-32。可能当时的人考虑的每次UniCode编码扩展都要重写底层很麻烦,所以才采用了自己的方式扩展。详情请访问:https://www.ibm.com/developerworks/cn/java/j-unicode/。我也是参考这篇博客来的。总之编码问题是变成路上不可避免的问题,但其实问题也不大,一般公司内部会统一编码,通常都是UTF-8。

  • 相关阅读:
    MySQL5.7修改默认密码、随机密码
    Java基础知识_毕向东_Java基础视频教程笔记(26 反射)
    Java基础知识_毕向东_Java基础视频教程笔记(22-25 GUI 网络编程 正则)
    Java基础知识_毕向东_Java基础视频教程笔记(19-21 IO流)
    Java基础知识_毕向东_Java基础视频教程笔记(14-18集合框架)
    Java基础知识_毕向东_Java基础视频教程笔记(13 字符)
    Java基础知识_毕向东_Java基础视频教程笔记(11-12 多线程)
    JIT和AOT编译详解
    PAT 说反话
    PAT 程序运行时间
  • 原文地址:https://www.cnblogs.com/ben-mario/p/10458318.html
Copyright © 2020-2023  润新知