String类源码阅读记录

在开发过程当中String是一个高频使用的类,可是一直没有仔细去阅读过源码。打开源码得知String是一个final的类,它实现了Serializable、Comparable和CharSequence接口java

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0
    //省略...
}

String类包含三个属性:数组

/** 存储字符串中的字符*/
    private final char value[];

    /** 缓存string的hashcode值 */
    private int hash; // Default to 0
    /**
     * 序列持久化
     */
    private static final ObjectStreamField[] serialPersistentFields =
            new ObjectStreamField[0];

String的底层使用char数组实现的。String重写了Object的equals和hashcode的方法。缓存

String的equals方法实现以下:jvm

/**
 * 比较当前字符串和指定的对象,只有当指定对象不为null而且对象中的字符序列相同时
 * 才返回true
 */
public boolean equals(Object anObject) {
    //两个对象的引用地址相同返回true
    if (this == anObject) {
        return true;
    }
    //只有String类型的数据才有效
    if (anObject instanceof String) {
        String anotherString = (String) anObject;
        int n = value.length;
        //若是包含的字符长度不相等返回false
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            //从后往前判断单个字符,同等序号若是不相等则返回false
            while (n-- != 0) {
                if (v1[i] != v2[i])
                        return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

String的hashCode实现以下:测试

String是使用value值来做为hash运算,那么若是String的value相等那么它们的hashCode值一定相等,那么用String的equals比较也是相等的,同时也能够看出对于String若是它的equals相等,那么它的hashCode值优化

也必定相等,固然hashCode值相等不能表明两个String相等。this

在String的Hash计算中使用一个计算常数31,31是通过测试均匀分布的获得的结果,并且31能够被jvm优化采用移位运算31 = (i<<5)-1code

/**
     * 返回字符串的hash值
     * 计算公式:
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * s[i]是指String中的字符,n是指String的长度
     */
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

String intern方法介绍:intern方法是一个native的方法,当intern方法被调用,它会使用equals方法去字符串常量池中比较查找,若是找到则返回,若是没有找到的将新的字符串添加到字符串常量池中,而后返回对象的引用。对于任何的两个String对象s和t,当前仅当s.equals(t)为true时,s.intern()==t.intern()才为true对象

public native String intern();

 

String的内存操做:接口

在jvm内存分配中有两个重要的部分,一个是heap一个是stack,栈用于存储对象的引用,

heap用户存储具体的对象。在jdk1.7后(字符串常量池被移到了heap中)jvm分配 一些内存专门用于存储string的字面量,这是堆内存的一部分,它被称做字符串常量池(String Constant Pool),例如 :String a = "abc"; 若是使用了new操做来建立字符串则对象会被存储到堆内存中

注意:当你使用一个字面量来建立一个String对象时,jvm会首先在字符串常量池中检查是否已经存在,若是找到则返回对象的引用,若是没有的建立一个新的对象

相关文章
相关标签/搜索