Java 的 IO 系统是比较庞杂的, 各种流特别多, 其中有一种就是字符流.
在本系列前面的一些文章中, 也曾涉及过字符流的话题, 不过没有详细展开讨论, 这次准备具体综合地谈一谈.
在层次方面的对比
你可能听过不少关于字节流与字符流对比的介绍, 不过严格地说, 我认为把"字节流"和"字符流"去对比这种说法不是特别妥当, 为什么呢?
首先, 这两种流实际上处在不同的层次, 字节流是基础, 而字符流是构建在其上的:
对于不同层次上的事物, 我认为用"对比"这个词是不太恰当的.
Java 的 IO 系统是比较庞杂的, 各种流特别多, 其中有一种就是字符流.
在本系列前面的一些文章中, 也曾涉及过字符流的话题, 不过没有详细展开讨论, 这次准备具体综合地谈一谈.
你可能听过不少关于字节流与字符流对比的介绍, 不过严格地说, 我认为把"字节流"和"字符流"去对比这种说法不是特别妥当, 为什么呢?
首先, 这两种流实际上处在不同的层次, 字节流是基础, 而字符流是构建在其上的:
对于不同层次上的事物, 我认为用"对比"这个词是不太恰当的.
判断一个字符是 BMP 字符还是非 BMP 字符(增补字符), 以及判断字符串中是否包含非 BMP 字符.
在 Java 中, 要判断一个字符是否为增补字符, 也即所谓的非 BMP 字符, 可以综合使用 String
类中的 codePointAt
和 Character
类中的 isSupplementaryCodePoint
方法, 具体如下:
@Test
public void testSupplementaryCodePoint() throws Exception {
// 一个非 BMP 字符
String s = "𧿹";
// 长度为 2
assertThat(s.length()).isEqualTo(2);
// 属于增补字符
assertThat(Character.isSupplementaryCodePoint(s.codePointAt(0))).isTrue();
}
当然也可以简单地尝试将这个字符赋值给一个 char 变量, char 变量只能接受一个 BMP 字符, 如果是非 BMP 字符, 则编译不通过. 如果是一串的字符, 想知道其中是否存在非 BMP 字符, 则可以使用 codePointCount
方法:
@Test
public void testCodePointCount() throws Exception {
String normalStr = "hi你";
String strContainNoneBMP = "h𧿹你";
// 两者的 length 不同
assertThat(normalStr.length()).isEqualTo(3);
assertThat(strContainNoneBMP.length()).isEqualTo(4);
// 两者的码点数( code point count)却是相同的
assertThat(normalStr.codePointCount(0, normalStr.length())).isEqualTo(3);
assertThat(strContainNoneBMP.codePointCount(0, strContainNoneBMP.length())).isEqualTo(3);
}
一个字符占几个字节? 很多人喜欢问这个问题, 遗憾的是他们没有意识到这其实是一个糟糕的问题, 因为它缺乏了必要的前提...
这是一个来自知乎上的问题, https://www.zhihu.com/question/27562173 , 提问者问:
Java 中理论说是一个字符(汉字 字母)占用两个字节. 但是在 UTF-8 的时候
new String("字").getBytes().length
返回的是 3 表示 3 个字节 小白求回答. .
严格地讲, 这个问题本身就是有问题的, 因为它缺少了前提, 在我的回答中我也强调了这一点, 回答具体如下:
首先, 你所谓的"字符"具体指什么呢? 如果你说的"字符"就是指 Java 中的 char, 那好, 那它就是 16 位, 2 字节.
如果你说的"字符"是指我们用眼睛看到的那些"抽象的字符", 那么, 谈论它占几个字节是没有意义的.
具体地讲, 脱离具体的编码谈某个字符占几个字节是没有意义的.
Java 之父 James Gosling 在一次接受采访谈到 C 语言时说:C 语言的一个大问题之一是“一切都会尖叫着停止”,"Everything comes to a screeching halt" is one of the big issues in C, because of the way that they do pointers……
语言的鄙视链是一直存在的,有人会以自己使用的语言更灵活,更底层,效率更高而自豪乃至鄙视其它一些语言的使用者,比如 C 语言的使用者可能看不上 Java 语言的使用者。Java 之父有一次谈到了 Java 与 C 语言的对比,他是怎么说的呢?
摘要: 深入探讨了 Java 线程的 TIMED_WAITING 状态