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原创文章,未经本站允许不得转载。