java String源码解析
学习Java ,很重要的一点就是要学会看Java源码, rt.jar 包就是 运行时库的jar 包,这里里面包含了基本的类库的源代码, jre 使我们的机器能运行Java程序, 而jdk 则是编译Java代码。看源码对我们理解Java的一些原理有很大的帮助,源码就是 jdk1.6/src.zip, 用eclipse 关联它(window->preference->java->installed jre ->jdk1.6 ->选择右侧的编辑->rt.jar->source attachment ->选中你的 jdk1.6/src.zip所在的位置即可) 我们就可以在eclipse中打开了 源码了。
现在进入正题,先看String的源码是怎么写的
public String(String original) { this.value = original.value; this.hash = original.hash; }
这里value 源码定义为private final char[] value; 所以当我们创建一个String对象的时候 其实就相当于把值赋给了char [] ,所以String的值和长度是不可变更的 。
这里我们再看看一个很经典的面试问题: String s= new String("xyz"); 这个语句 到底创建了几个对象? 这个问题值得深思 我浏览了一些文章 分析如下:
“xyz”是一个String对象 JVM 首先会在String 池 中搜寻"xyz"对象 如果没有就在String池中 创建一个“xyz”对象,然后遇到new 运算符 在内存中(jvm堆中)构造一个String类对象 ,最好把对象的地址赋给对象引用s。所以这里总共创建了两个对象。第一个是在String池中创建,第二个是在内存中创建。(这里还需注意一点 jvm中 对象储存在堆内存中 变量储存在栈内存中)
再看看一段代码:
String s = "hello"; String s1 = new String("hello"); String s2 = "hello"; System.out.println(s == s1); System.out.println(s == s2);输出 false
true
在java运算符中== 是比较两个变量的地址 ;所以我们可以看出 s和s1所引用的地址不是同一个,而s 和s2是同一个地址,也就是引用了同一个对象。我们这样分析:第一条语句:jvm在String池中用equals()方法搜索“hello”对象 没有该对象,创建“hello”对象,返回该地址给S;第三条语句:由于 String池中已经存在“hello”对象,所以直接返回地址给S2;所以 s跟s2的地址相同 输出true;
而 第二条语句 是在堆内存中穿了一个对象 并把地址返回给s1,所以 s跟S1地址不相同,输出false;
equals()方法,源码贴出:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String) anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }这句话的意思是对比两个对象的个数和内容,只要有其中一项不符合 就返回false 否则就返回true 也就是对比两个对象的内容
例子:
String s = "hello"; String s3=new String("hello"); System.out.println(s.equals(s3));输出
true
compareTo()方法 是比较两个String 对象的
贴源码:
public int compareTo(String anotherString) { int len1 = count; int len2 = anotherString.count; int n = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; if (i == j) { int k = i; int lim = n + i; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } } else { while (n-- != 0) { char c1 = v1[i++]; char c2 = v2[j++]; if (c1 != c2) { return c1 - c2; } } } return len1 - len2; }
如果两个字符串 例如 s=new String("hello") s2=new String("h") 前面的h相等 也就是c1[0]=c2[0] 然后 执行 len1-len2=4
String s="hello"; String s1="h"; System.out.println(s.compareTo(s1));
输出
4
上面的源码中return c1-c2 就是得到两个unicode码的差值
例如
String s="hello"; String s1="hb"; System.out.println(s.compareTo(s1));
第一个值相等 比较第二个'e'-'b'=3
输出为
3
版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。