> 文档中心 > 【Java源码分析】String 字符串属性

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

目录

      • 字符串状态
        • length()
          • 语法
          • 参数
          • 返回值
          • 实例
          • 源码
        • hashCode
          • 语法
          • 参数
          • 返回值
          • 实例
          • 源码
        • intern()
        • toString()

字符串状态

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

海量搞笑GIF动态图片