char字符Java_【Java】 基础篇 -- 字符 char

char 在 Java 中是个很底层的东西了,比如 String 、StringBuilder 的底层就是它,但是在我们平时的工作中呢,很少使用他,不过既然是底层,今天我们大家就来一起研究下这 “哥们”。

char 用来表示 1 个字符 。也就是说,如果你写 2个字符,那么这里是会报错的。如下:

// 这种编译报错 Too many characters in character literal

char c = '中国';

当然 char 也可以用来表示中文字符。在赋值时,我们经常这样表示:

char c = '中';

char c1 = 'H';

但是这里就会遇到一些面试上的坑了,比如使用字符类型进行算术运算和比较运算? 这是个什么鬼 A + B == ???

其实在 Java 内部进行字符处理时,采用的是 Unicode,(这里插一句 对 Unicode 和 UTF-X 的理解,Unicode 是一个包含世界各国字母的字符列表的编码。 Universal Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “unicode “,就是每一个字母对应一个编码 ID,是一种映射关系,我们可以理解为 Unicode 是 一个标准,一个规则,而 UTF-X 则是一种具体的对 Unicode 的实现,UTF-X 是一种 针对 Unicode 的可变长度字符编码,也是一种前缀码,是一种编码格式。它可以用来表 示Unicode标准中的任何字符,而且 UTF-8 是兼容 ASCII 的。UTF-8 是 Unicode 的 实现方式之一。)

char 本质上是一个固定占用 2 个字节的无符号正整数,对应 Unicode, 也就是说 上面 的 李, H 都分别对应一个 正整数,char 只能表示 Unicode 编号在 65 536 以内的字符。因为一个字节 只能表示 256 个符号,2 个字节就是 256 x 256 = 65536 个符号。那么如果超出范围该咋表示呢,用 2 个char!!!

既然了解完了 Unicode,那么每个字符都可以用一个 对应的 编码ID 表示,也就是 一个正整数。既然是数字了,自然可以进行算术运算和比较运算。

char 的 二进制转换

下面我们就以 Integer 的转换二进制函数 toBinaryString 为例,说明一下 char 字节在 Java 中如何转换二进制的。

public static void main(String[] args) {

char c = '中';

System.out.println(Integer.toBinaryString(c));

// 二进制为: 100111000101101

}

我们给 char 赋值一个 中文 字节 中,然后求出它的 二进制。

Integer 的 toBinaryString 方法:

/**

* 返回 输入参数 i 的 二进制字符串

*/

public static String toBinaryString(int i) {

return toUnsignedString0(i, 1);

}

这里调用了 toUnsignedString0, 如下

/**

* Convert the integer to an unsigned number.

* 转换一个 整型到一个无符号二进制数字

*/

private static String toUnsignedString0(int val, int shift) {

// 这里断言忽略

// assert shift > 0 && shift <=5 : "Illegal shift value";

// Integer.numberOfLeadingZeros 返回无符号整型的最高非零位前面的0的个数,包括符号位在内

// 比如 Integer.numberOfLeadingZeros(10) 结果是 28

// Integer.SIZE 为 32

int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);

int chars = Math.max(((mag + (shift - 1)) / shift), 1);

char[] buf = new char[chars];

// 这里是整个方法的核心,整数转换二进制,然后更新 char 的缓冲

formatUnsignedInt(val, shift, buf, 0, chars);

// Use special constructor which takes over "buf".

return new String(buf, true);

}

核心转换函数 formatUnsignedInt 如下:

/**

* 格式化到字符缓冲区

* @param val 被格式化的数

* @param shift 格式化的类型 (4 代表16进制, 3 代表8进制, 1 代表二进制)

* @param buf 待写入的字符缓冲区

* @param offset 字符开始的位置

* @param len 要写的字符数

* @return the lowest character location used

*/

static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {

int charPos = len;

int radix = 1 << shift;

int mask = radix - 1;

do {

// 二进制的 & 运算,求出下标,然后获取 digits 中对应的值,写入 buf 缓冲区

// final static char[] digits = {

// '0' , '1' , '2' , '3' , '4' , '5' ,

// '6' , '7' , '8' , '9' , 'a' , 'b' ,

// 'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,

// 'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,

// 'o' , 'p' , 'q' , 'r' , 's' , 't' ,

// 'u' , 'v' , 'w' , 'x' , 'y' , 'z'

}

buf[offset + --charPos] = Integer.digits[val & mask];

// 无符号右移

val >>>= shift;

} while (val != 0 && charPos > 0);

return charPos;

}

通过上面的代码可以看出,Integer 内部维护了一个 char 数组,我们的普通字符转换 二进制的时候,都是求出 digits 某个下标的值,然后写到缓冲区,以 String 的形式返回给用户的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值