一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
String的特性
String可能是Java中最特殊的一个数据类型
- 和基本数据类型的封装类型一样,具备不可变性
//不能被继承,不能从外部修改value
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
@FastNative
public native char[] toCharArray();
//外部调用都是通过native来返回的
public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(this, beginIndex);
}
int subLen = length() - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(this, beginIndex);
}
return (beginIndex == 0) ? this : fastSubstring(beginIndex, subLen);
}
@FastNative
private native String fastSubstring(int start, int length);
public int hashCode() {
int h = hash;
final int len = length();
if (h == 0 && len > 0) {
for (int i = 0; i < len; i++) {
h = 31 * h + charAt(i);
}
hash = h;
}
return h;
}
}
String实例的使用主要是对字面量的使用,更接近基本数据类型。
- 声明方式像基本数据类型,但其实是引用类型
- 作为引用类型,又不一定直接放在堆里,有可能放在字符串池(String Pool)中
线程安全度递减模型
字符串池和常量池
- 每个类在运行时,都有自己的,与class文件对应的运行时常量池
- 字符串池用来存全局驻留字符串的,Hotspot虚拟机中,通过一个hash表来实现
- 常量池中的CONSTANT_String类型,会通过查询字符串池去进行解析,以保证二者对应的字符串实例是一致的。
intern方法的作用
JDK 1.7一下,字符串池在永久代,intern方法的含义是:
- 如果字符串池中存在与当前字符串内容相同的缓存,则返回缓存实例否则在字符串池中创建相应实例,并返回 JDK1.7及以上,字符串池在堆中,字符串池中,存储的是字符串堆引用,ittern方法的含义是
- 如果字符串池中存在与当前字符串内容相同的缓存,则返回缓存的引用,否则则在字符串池中存储当前字符串的引用
Hash(散列算法)
就是把任意长度 的输入,或者叫做预映射(pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是散列值的空间通常远小于输入空间,不同的输入可能会散列程相同的输出,而不可能从散列值来唯一的确定输入值.
java中的hashcode方法
- 返回实例的散列值,这个方法主要是为了哈希表提供的
- 只要不改变equals方法中使用的比较信息,每次在同一个实例上调用hashcode方法,必须始终返回相同的整数。但是在下一次程序执行时,改整数不必保持一致
- 通过equals方法比较相等的两个实例,他们调用hashcode得到的整数必须相同
- 通过equals方法比较不相等的两个实例,他们调用hashcode得到的整数可以相同,但是最好不相同,因为有助于提高哈希表的性能
String的hashCode选择乘数31的原因
- 可以把四则运算转换为位运算,提高性能
- 素数参与乘除运算,降低碰撞概率
- 大小适中,保证结果位数是中,减少碰撞