【Java源码分析】String 字符串属性

字符串状态

length()

length() 方法用于返回字符串的长度。

空字符串的长度返回 0。

语法
public int length()
参数
返回值

返回字符串长度。

实例

以下实例演示了 length() 方法的使用:

public class Test {
        public static void main(String args[]) {
                String Str1 = new String("Hello" );
                System.out.print("字符串 Str1 长度 :");
                System.out.println(Str1.length());

        }
}

以上程序执行结果为:

字符串 Str1 长度 :5
源码
 private final char value[];
 public int length() {
        return value.length;
    }

底层是一个数组,即数组的长度

hashCode

hashCode() 方法用于返回字符串的哈希码。

字符串对象的哈希码根据以下公式计算:

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

使用 int 算法,这里 s[i] 是字符串的第 i 个字符的 ASCII 码,n 是字符串的长度,^ 表示求幂。空字符串的哈希值为 0。

语法
public int hashCode()
参数
  • 无。
返回值

返回对象的哈希码值。

实例
public class Test {
        public static void main(String args[]) {
                String str = new String("1");
                System.out.println("字符串的哈希码为 :" + str.hashCode() );
        }
}

以上程序执行结果为:49,0的ascii是48

源码
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;
    }

目的,提高比较效率

(1)31是一个不大不小的质数,是作为 hashCode 乘子的优选质数之一

(2)31可以被 JVM 优化,31 * i = (i << 5) - i。

一般在设计哈希算法时,会选择一个特殊的质数。至于为啥选择质数,应该是可以降低哈希算法的冲突率。

intern()

intern() 方法返回字符串对象的规范化表示形式。

它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

所有文字字符串和字符串值的常量表达式都是intern。

给String类中加入这个方法可能是为了提升一点点性能,因为从常量池取数据比从堆里面去数据要快一些。

返回

与此字符串具有相同内容的字符串,但保证来自唯一字符串池。

实例

        String str1 = "aaa";

        String str2 = "bbb";

        String str3 = "aaabbb";

        String str4 = str1 + str2;

        String str5 = "aaa" + "bbb";

        String str6 ="aaa".concat("bbb");

        System.out.println(str3 == str4.intern()); // true
        System.out.println(str3 == str4);// false
        System.out.println(str3 == str5);// true
        
        System.out.println(str3 == str6);// false
        System.out.print("规范表示:" );
        System.out.println(str1.intern());

结果:str1、str2、str3、str5都是存在于常量池,str4由于表达式右半边有引用类型,所以str4存在于堆内存,而str5表达式右边没有引用类型,是纯字符串常量,就存放在了常量池里面。其实[integer这种包装类型的-128 ~ +127也是存放在常量池里面,比如Integer i1 = 10;Integer i2 = 10; i1 == i2结果是true,也是为了性能优化。

concat链接的字符串都是new,所以放在堆内存。

toString()

toString() 方法返回此对象本身(它已经是一个字符串)。

源码

public String toString() {
        return this;
    }

猜你喜欢

转载自blog.csdn.net/qq_15604349/article/details/124363797