现在的位置: 首页 > 综合 > 正文

JavaSE第二十九讲:String类源代码深剖析

2013年05月05日 ⁄ 综合 ⁄ 共 4516字 ⁄ 字号 评论关闭

1.JDK中的Object类里面的equals()方法: public boolean equals(Object obj)

  先了解以下equals()方法,equals[相等]首先要明确几点:

1):equals()是定义在Object类中的。

2):equals()本身接受一个Object类型的参数。

3):equals()的返回类型是boolean型的。

    改方法判断当前的这个对象跟其传进来的对象是否相等。

public class StringTest{
	public static void main(String[] args){
		String str = new String("aa");
		String str2 = new String("aa");
		System.out.println(str.equals(str2));  //输出为true,以为str和str2他们字符串的内容一样。

		String str3 = "bb";
		String str4 = "bb";
		System.out.println(str3.equals(str4)); //输出为true,因为str3和str4字面上的值一样,所以输出为真。注:这里通常叫str3和str4为字面上的值一样。

		System.out.println("--------------");
		Object object = new Object();
		Object object2 = new Object();
		System.out.println(object.equals(object2));//输出假,究其原因请看JDK提供的各个类的源代码。
	}
}


编译执行结果:

D:\src>java StringTest
true
true
--------------

false

【注意】:接下来的学习过程中,有碰到难题最好能在源代码当中寻求解决办法,因为源代码才是精髓。

查看equals()源代码:java安装目录/jdk/src.rar解压,在java/lang/Object.java文件中找到equals()方法

    public boolean equals(Object obj) {
        return (this == obj);
    }

【说明】:equals()方法,this为当前对象,谁调用了equals()方法,谁就是当前对象;obj为传进来的参数。

return(this
== obj);这个理解为:调用了equals()的这个引用传进来的这个引用否指向同一个对象,也就是他们的地址是否相等。如果返回时true,则表示他们指向同一个对象,则这两个引用相。所以上面一个例子第三组数据指向的是不同的对象,所以输出结果为false。

2.
equals()方法,该方法定义在Object类当中,因此Java中的每个类都具有该方法,对于Object类的equals()方法来说,它是判断调用equals()方法的引用与传进来的引用是否一致,即这两个引用是否指向的是同一个对象。对于Object类的equals()方法来说,它等价于==。

public class StringTest{
	public static void main(String[] args){
		String str = new String("aa");
		String str2 = new String("aa");
		System.out.println(str.equals(str2));  //输出为true,以为str和str2他们字符串的内容一样。

		String str3 = "bb";
		String str4 = "bb";
		System.out.println(str3.equals(str4)); //输出为true,因为str3和str4字面上的值一样,所以输出为真。注:这里通常叫str3和str4为字面上的值一样。

		System.out.println("--------------");
		Object object = new Object();
		Object object2 = new Object();
		System.out.println(object.equals(object2));//输出假,究其原因请看JDK提供的各个类的源代码。
		System.out.println(object.equals(object));
	}
}

编译结果:

D:\src>java StringTest
true
true
--------------
false
true

【说明】:最后一行代码System.out.println(object.equals(object));他们为true,因为相同的引用指向同一个对象了。

对比这两段程序:

		String str = new String("aa");
		String str2 = new String("aa");
		System.out.println(str.equals(str2)); 

		Object object = new Object();
		Object object2 = new Object();
		System.out.println(object.equals(object2));

这两组代码,上一组执行结果输出为true,下一组执行输出为false,显然他们的行为是不同的,即便他们都是用new 对象的方式,从这边可以看出String类已经对其父类Object类的equals()进行重写了。所以此时看JDK的String类的equals()方法的内容。

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

【剖析这段源代码】:public
boolean equals(Object  anObject) 重写了父类的这个方法,所以放回类型boolean,参数类型Object都不变,不然就变为重载了,Java源代码竟然都把匹配字符串的算法也给嵌进去了,不错O(∩_∩)O~,

if(this == anObject)与Object类里面equals()方法类似,表示调用的参数与传进来的参数如果是一样的,就为真,返回true,即自己与自己比,直接返回真,如果不满足,则进入if (anObject instanceof String)判断传进来的参数是否是String的实例,如果不是直接放回false,即传进来的对象与另外一个对象进行比较,类似一只猫与一只狗进行比较,所以直接返回false。如果是传进来的参数是String的实例,则进入if语句里面的执行,首先要执行String
anotherString = (String)anObject;将这个anObject的这个实例向下转型为String类型,因为anObject是Object类型的,String类继承了Object,所以要进行向下转型为String类型才能享有String类里面的所有方法。此时开始进行字符串的匹配。

找个时间用活动图来画出来吧。O(∩_∩)O~

3.
对于String类的equals()方法来说,它是判断当前字符串与传进来的字符串的内容是否一致。

4.
对于 String 对象的相等性判断来说,请使用 equals()方法,而不要使用==。 【注意】:此处经常有人在面试的时候会问到equals()方法的意思,不能笼统的回答:equals是判断两个内容是否相同,=是判断两个引用是否一致,这种说法是不准确的,正式的回答是:对于Objectequals()方法来说是判断两个引用是否一致,是否指向同一个对象,而对于其他继承了Object类的其他类,如果它重写了Object类的equals()方法,它才是判断其内容是否一致,如果没有重写的话则和Object类的equals()方法判断方式一样。

以下例子解读:

public class EqualsTest{
	public static void main(String[] args){
		Student s1 = new Student("zhangsan");
		Student s2 = new Student("zhangsan");
		System.out.println(s1 == s2);
		System.out.println(s1.equals(s2));
	}
}

class Student{
	String name;
	public Student(String name){
		this.name = name;
	}
}

编译执行结果:

D:\src>java EqualsTest
false
false

【说明】:此时System.out.println(s1.equals(s2));这句与System.out.println(s1 == s2);效果是一样的,因为Student类没有重写Object类的equals(),所以其实都是沿用父类Object类里面的equals方法。

比较之前的equals()方法本义是比较内容是否一样,重写父类的equals()方法,将其实现判断传进去的两个人的名字一样,则他们是同一个人,如下:

public class EqualsTest{
	public static void main(String[] args){
		Student s1 = new Student("zhangsan");
		Student s2 = new Student("zhangsan");
		System.out.println(s1 == s2);
		System.out.println(s1.equals(s2));
	}
}

class Student{
	String name;
	public Student(String name){
		this.name = name;
	}

	public boolean equals(Object anObject){
		if(this == anObject){
			return true;
		}
		if(anObject instanceof Student){
			Student studentString = (Student)anObject;
			if(studentString.name.equals(this.name)){
				return true;
			}
		}
		return false;

	}
}

编译结果:

D:\src>java EqualsTest
false
true

【注意】:这里面匹配两个人的名字是否相同是直接调用String类里面的equals()方法了,而不是实现一个匹配两个人的名字是否一样的算法。






抱歉!评论已关闭.