length()
checkBoundsBeginEnd()
length()
源码:
public int length() {
return value.length >> coder();
}
分析:
/*
eg.
value.length == 13
coder() == 1
13 >> 1 13 => 6
0000 1101 >> 1 =>0000 0110
可以看出同一个字符串 不同的编码格式,对应长度可能会出现不一样
*/
public int length() {
return value.length >> coder();
}
@Native static final byte LATIN1 = 0;
@Native static final byte UTF16 = 1;
//是否采用紧凑字符串模式
private final byte coder;
static final boolean COMPACT_STRINGS;
static {
COMPACT_STRINGS = true;
}
byte coder() {
return COMPACT_STRINGS ? coder : UTF16;
}
结论:
同一个字符串 不同的编码格式,对应长度可能会出现不一样
拓展:
紧凑字符串模式(Compact Strings Mode)是一种 Java 虚拟机(JVM)的优化技术,用于更有效地存储字符串对象,特别是在字符串包含大量 Latin-1 字符时。它是自 Java 9 版本以来引入的一项性能优化。
在传统的 Java 中,每个字符通常用 16 位(2 字节)的 UTF-16 编码表示。但对于大多数英文文本和许多其他语言的文本,大部分字符都可以使用 Latin-1 编码(1 字节)来表示。因此,对于包含大量 Latin-1 字符的字符串,使用 16 位编码存储会浪费内存空间。
紧凑字符串模式的关键思想是,对于适合使用 Latin-1 编码的字符串,Java 会使用单字节编码来存储这些字符,从而减少内存消耗。只有当字符串包含非 Latin-1 字符时,才会切换回标准的 UTF-16 编码。这个优化是透明的,开发者无需修改代码,Java 虚拟机会根据字符串内容自动选择适当的编码方式。
使用紧凑字符串模式可以带来以下好处:
-
节省内存: 对于包含大量 Latin-1 字符的字符串,内存使用效率得到显著提高,因为每个字符只需要一个字节来表示。
-
减少内存垃圾收集开销: 较小的对象通常会减少垃圾收集的负担,因为垃圾收集会涉及遍历和处理对象。
-
提高性能: 减少内存使用可以提高应用程序的性能,因为更少的内存操作通常会更快。
要启用紧凑字符串模式,通常只需使用支持 Java 9 或更高版本的 JVM,因为这个优化是默认启用的。但是,请注意,紧凑字符串模式不适用于所有情况,它主要针对包含大量 Latin-1 字符的字符串。在某些情况下,它可能会导致性能下降,因此在使用时需要谨慎测试和评估。
checkBoundsBeginEnd()
源码:
static void checkBoundsBeginEnd(int begin, int end, int length) {
if (begin < 0 || begin > end || end > length) {
throw new StringIndexOutOfBoundsException(
"begin " + begin + ", end " + end + ", length " + length);
}
}
分析:
正常情况下,对于检查一个字符串的begin 和 end
会想到如下情况:
begin < 0
end < 0
length < 0
end < begin
end < length
但是,我们看源码
当每个条件分别为False时,可以推出的情况
1.begin < 0 =>begin >= 0
2.begin > end => end >=0
3.end > length => length >0
只有情况1成立,才有可能判断情况2,最后判断情况3
相比一开始的分析,源码中可以不写 end < 0 ,length < 0