在java中,我们会测试两个变量是否相等有两种方式
1.==比较
2. equals方法
我们常常会被这两个方法弄的很晕,这篇算是终极篇。反正写这篇文章的时候我是弄懂了。不再迷惑了。
java中,数据类型分为基本数据类型和引用类型,基本数据类型就是那八种:
byte short int long char float double boolean
他们都有自己的包装类
引用类型有哪些呢?
类下的所有引用变量 数组 字符串
知道这个跟我们讲的两个比较方法有什么关系呢?
1.基本类型变量用==比较方法,对比的时候类型没有严格要求,只要数值一样即可。
public class LearnEqualsDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a = 100;
int b = 100;
char c = 100;
Long L = 100L;
float f = 100.0f;
double d = 100.00;
System.out.println(a == b);
System.out.println(b == c);
System.out.println(b == L);
System.out.println(b == f);
System.out.println(b == d);
}
}
//返回的都是true
不是还有一种字符串类型的没有进行比较吗?
字符串变量直接赋值的形式 例如 String str = "abc";
会有点特殊。它是存在常量池中的。
首先字符串直接量是放在常量池中的。也就是堆内存中的方法区(类的代码信息,比如有什么方法)。上面代码中的main方法中,也是在堆内存中开辟一个方法区,用来存放static修饰的变量,方法区里面有一个常量池,用来存放字符串的赋值。
堆内存 –>开辟一个方法区–>里面有三个东西{1.类的代码信息(eat(); run();) 。2.static变量 3.常量池(字符串常量)
字符串常量就存在常量池中,两个要比较的字符串直接量用==进行比较,例如
String str ="abc";
String str2 = "abc";
System.out.println(str== str2);//true
就是相当于在同一个常量池取同一个数据abc,那值肯定会相等。
引用类型用==可以进行比较吗?
当然可以。==在引用类型中比较的是引用变量是否 指向同一个对象。
在对象的生成中,会在堆内存中开辟一个空间,用来存放这个对象。
只要在语句中有出现new这个字眼,就是告诉编译器,给我单独开辟一个空间出来,所以,有new 这个字眼的对象都是不同的对象。
String str3 = new String("hjm");
String str4 = new String("hjm");
System.out.println(str3 == str4);//false
为什么呢?因为他们有new 这个字眼,按照上面所说的,有new 就是开辟一个独立的空间,构造不同的对象。所以它们才不相等。
==讲完了,讲equals方法。
这个方法有点像自定义比较方法。就是我要怎么比就怎么比。
但是Object类默认比较的是对象是否一样。
public boolean equals(Object obj) {
return (this == obj);//==在引用类型中比较的是引用变量是否 指向同一个对象。
}
我们可以自己定义equals方法,不然的话都是默认继承基类Object的比较方法。
我们的字符串类String就比较积极,重写了父类的equals方法。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
首先也是比较是否是同一个对象。是的话直接true。不是的话再比较 String类型下的值是否一样,一样返回true。
最后都没有就是false。
既然我们说equals是自己定义的比较方法,内容自定。但是我们想要让两个变量相等的话是不是属性值一样就可以变成指向同一个对象呢?
这里面就有这么一个坑,那就是hashCode这个坑。如果要真正让对象变量相等的话,也要重写hashCode方法。可以看下另外一篇
http://blog.csdn.net/hejiajiaming/article/details/76794381
这篇专门讲重写equals方法里面有哪些坑!
本文思路来自《疯狂java讲义》
我只是大自然的搬运工。