• 001. Java内存中的字符编码


      Java内存中的字符编码

    Unicode字符集及utf-8 、utf-16、utf-32 等字符编码方式

    字符集:字符表示的数字集合,元素称为码点或码位;

    字符编码:字符实际的储存表示;

    码点:一个码点对应 一个字符;

    utf-8编码:可变长编码,一个字符编码使用 1或2或3或4个字节表示; https://blog.csdn.net/hezh1994/article/details/78899683

    utf-32编码:定长编码,一个字符编码使用4个字节

    utf-16编码:结合可变长编码及定长编码,BMP平面字符编码2个字节,SMP平面字符比编码使用4字节; 

     

    Java内存中字符(char变量或String(char[]))以utf-16BE编码存在

     
    utf-16 BMP平面(代理区U+0000至U+FFFF除外)的码点,以1个码元(16比特即2字节)编码;SMP平面的码点以2个码元(32比特)编码

    因此Java内存中char类型变量只能表示BMP平面的一个字符,表示SMP平面的字符使用String对象。 

    String str = new String(Character.toChars(0x1D56B)); // 一个字符

    字符从内存输出,如何显示在屏幕 ?

    //System.out.println(strings);

    System.out.print() 将内存中的字符串(char[])按utf-16解码为unicode码点,再以系统编码方式(如utf-8,将码点编码)输出字节流,
    控制台收到的字节流,以相同的方式(utf-8)解码为unicode码点
    系统将码点以图形的形式显示

    测试代码

    (1)SMP平面字符

    String str = new String(Character.toChars(0x1D56B)); //UTF-16 representation stored ,所以这个unicode扩展字符保存在内存的需要 2个char

    System.out.println("码点: "+Integer.toHexString(str.codePointAt(0)));
    System.out.println("utf-8编码的内存形式: 字节数量 "+str.getBytes().length); //4
    System.out.println("utf-8编码的内存形式: 字节序列 "+Arrays.toString(str.getBytes())); //IDE设置使用 utf-8
    System.out.println("utf-16编码的内存形式: 双字节(码元)数量 "+str.toCharArray().length); //2
    System.out.println("utf-16编码的内存形式: 双字节(码元)序列 "+"["+Integer.toHexString((int)str.charAt(0))+","+Integer.toHexString((int)str.charAt(1))+"]");
    //System.out.println(str.toCharArray()); //显示为特殊字符
    System.out.println("字符串长度(码元): "+str.length()); //2 java统计字符串长度实际是计算char[]数组长度(码元总数),而不是字符(码点)个数
    System.out.println("字符串字符(码点)个数: "+str.codePointCount(0,str.length())); //1

    输出结果:

    码点: 1d56b
    utf-8编码的内存形式: 字节数量 4
    utf-8编码的内存形式: 字节序列 [-16, -99, -107, -85]
    utf-16编码的内存形式: 双字节(码元)数量 2
    utf-16编码的内存形式: 双字节(码元)序列 [d835,dd6b]
    字符串长度(码元): 2
    字符串字符(码点)个数: 1

    (2)BMP平面字符

    String s = new String(Character.toChars(0x4f60));
    System.out.println("码点: "+Integer.toHexString(s.codePointAt(0)));

    System.out.println("utf-8编码的内存形式: 字节数量 "+s.getBytes().length); //3
    System.out.println("utf-8编码的内存形式: 字节序列 "+Arrays.toString(s.getBytes())); //IDE设置使用 utf-8
    System.out.println("utf-16编码的内存形式: 双字节(码元)数量 "+s.toCharArray().length); //1
    System.out.println("utf-16编码的内存形式: 双字节(码元)序列 "+"["+Integer.toHexString((int)s.charAt(0))+"]");
    System.out.println("字符串长度(码元): "+s.length()); //1 java统计字符串长度实际是计算char[]数组长度(码元总数),而不是字符(码点)个数
    System.out.println("字符串字符(码点)个数: "+s.codePointCount(0,s.length())); //1

    输出结果:

    码点: 4f60
    utf-8编码的内存形式: 字节数量 3
    utf-8编码的内存形式: 字节序列 [-28, -67, -96]
    utf-16编码的内存形式: 双字节(码元)数量 1
    utf-16编码的内存形式: 双字节(码元)序列 [4f60]
    字符串长度(码元): 1
    字符串字符(码点)个数: 1

  • 相关阅读:
    生成排列与生成子集
    赛后总结AtCoder Beginner Contest 090(Beginner)
    树状数组笔记
    论怎么记住tarjan的板子
    tarjan缩点-受欢迎的牛-笔记
    tarjan模板(%%%hzwer)-2.0
    tarjan模板(%%%hzwer)
    匈牙利算法学习笔记
    最短路-Car的旅行路线
    数据结构 笔记1 搜索树
  • 原文地址:https://www.cnblogs.com/badboyh2o/p/10092158.html
Copyright © 2020-2023  润新知