改动原因
最根本的改动目的是减少String占用的内存。
java8之前,String使用char[]存储,char占两个字节,但是很多时候String的字符我们可以用一个字节表示,使用char就会浪费。而byte只占一个字节,所以使用byte将会大大减少String的内存空间。
仅仅将char改为byte就行了吗
char使用的是UTF-16编码格式,占2个或4个字节;
如果要使用一个字节来表示一个字符,那么一定要用到ISO-8859-1即
LATIN1编码格式,所以java9的String,一定要具备两种编码格式,所以java9添加了coder来区分两种编码格式
@Native static final byte LATIN1 = 0;
@Native static final byte UTF16 = 1;
String.length()
java8之前,length()方法为:
public int length() {
return value.length;
}
直接返回char[]数组的长度即可 而java9以后:
public int length() {
return value.length >> coder();
}
byte coder() {
return COMPACT_STRINGS ? coder : UTF16;
}
在byte[]数组长度的基础上,右移了coder()位,
COMPACT_STRINGS压缩标志默认为true;
如果我们想关闭COMPACT_STRINGS功能则可以使用-XX:-CompactStrings参数。
coder是编码格式的值,LAATIN1为0,UTF-6为1;
所以在LAATIN1编码格式一个字节表示情况下,字符串长度为byte数组长度
在UTF-16两个或四个字节表示情况下,字符串长度为byte数组长度/2
indexOf();
与length方法一样,indexOf方法也添加了编码格式的判断
public int indexOf(int ch, int fromIndex) {
return isLatin1() ? StringLatin1.indexOf(value, ch, fromIndex)
: StringUTF16.indexOf(value, ch, fromIndex);
}