java中 equals()方法 与 “==”的区别
2018-02-27 16:18
381 查看
转自:java中 equals()方法 与 “==”的区别-sillyzql
个人看完博主写的二者之间的区别后,觉得写的很好,很清晰,所以转发一下,点击上面链接可查看原博文。摘要
java语言的 equals() 方法 与 “==” 的区别,是每个初学者都会遇到过的问题。之前自己也很清楚,可日子一长,又渐渐遗忘,于是整理出一篇博客,复习一下。1.基本数据类型
java的基本数据类型,也称为原始的数据类型。它们分别是:byte, short, char, int, long, float, double, boolean .
基本数据类型进行 “==” 比较时,比较的是 它们的值 是否相同。
例如:
int a = 10; int b = 10 System.out.println(" (a == b) = " + (a == b));
输出的结果为真。
另外需要注意的是,对于基本类型而言,它们没有 equals() 方法,大家别上当啊。
2. 复合数据类型(类)
1) 当 两个对象使用 “==” 进行比较时,比较的是它们在 内存中存放的地址。 也就是说,除非是 同一个new() 出来的两个对象(内存地址相同), 否则比较的结果都是false。具体测试代码如下:public class Main { public static void main(String args[]) { Worker worker1 = new Worker(); //worker2 是 worker1 的引用,同指向一个内存空间。 Worker worker2 = worker1; System.out.println("(worker1 == worker2) : " + (worker1 == worker2)); System.out.println("-------------------------"); Worker worker3 = new Worker(); //worker3 与 worker4 都是调用new 产生的对象,不指向同一个内存空间。 Worker worker4 = new Worker(); System.out.println("(worker3 == worker4) : " + (worker3 == worker4)); } } class Worker { private String name; private double salary; public Worker() { this.name = "echo"; this.salary = 0.0; } public Worker(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } 输出的结果: (worker1 == worker2) : true ------------------------- (worker3 == worker4) : false
2) 大家都知道java的所有类 都是从 java.lang.Object 这个类继承下来,而Object 类中原本就有一个 equals() 方法。首先,我们来看看源代码中 Object 类的equals() 方法。具体代码如下:
public boolean equals(Object obj) { return (this == obj); }
可以发现,默认情况下,当我们调用equals() 方法时,也仍然是比较两个对象 是否指向同一块内存空间。 我们 稍微 修改 上面的代码,进行测试。具体代码如下:
public class Main1 { public static void main(String args[]) { Worker worker1 = new Worker(); //worker2 是 worker1的引用,同指向一个内存空间。 Worker worker2 = worker1; System.out.println("worker1.equals(worker2) : " + worker1.equals(worker2)); System.out.println("-------------------------"); Worker worker3 = new Worker(); //worker3 与 worker4 都是调用new 产生的对象,不指向同一个内存空间。 Worker worker4 = new Worker(); System.out.println("worker3.equals(worker4) : " + worker3.equals(worker4)); } } class Worker { private String name; private double salary; public Worker() { this.name = "echo"; this.salary = 0.0; } public Worker(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } } 运行结果如下: worker1.equals(worker2) : true ------------------------- worker3.equals(worker4) : false
这个时候,大家一定有疑问了,不是都说,equals() 方法比较的是 两个对象的内容嘛? 没错,默认的约定是这样的。对于我们自己写的类,如果想要达到这个效果,那么就要重写 equals()方法了。具体代码如下:
(可以直接使用 eclipse的工具,选择自己想要进行比较的变量,自动生成 equals()方法)。
class Worker { private String name; private double salary; public Worker() { this.name = "echo"; this.salary = 0.0; } public Worker(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } //重写了Object类的 equals() 方法 @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Worker other = (Worker) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (Double.doubleToLongBits(salary) != Double .doubleToLongBits(other.salary)) return false; return true; } }
接下来,看一下测试类,以及运行结果:
public class Main1 { public static void main(String args[]) { Worker worker1 = new Worker(); //worker2 是 worker1的引用,同指向一个内存空间。 Worker worker2 = worker1; System.out.println("worker1.equals(worker2) : " + worker1.equals(worker2)); System.out.println("-------------------------"); Worker worker3 = new Worker(); //worker3 与 worker4 都是调用new 产生的对象,不指向同一个内存空间。 Worker worker4 = new Worker(); System.out.println("worker3.equals(worker4) : " + worker3.equals(worker4)); } } 运行结果如下: worker1.equals(worker2) : true ------------------------- worker3.equals(worker4) : true
3) 在jdk的源代码中,大部分的类都自己实现了 equals() 方法,例如我们熟悉的 String,Integer,Double,Long等。大家在使用jdk提供的类时,使用到 equals()方法,最好查看一下源码,保证不出错。
3. 怪异的String
上文说了,String类重写了 equals() 方法,当调用equals()方法比较两个String对象时,比较的是其内容,那 怪异二字 从何而来呢? 且看下面代码:public class Main2 { public static void main(String args[]) { String s1 = "hello world"; String s2 = "hello world"; System.out.println("s1.equals(s2) : " + s1.equals(s2)); System.out.println("(s1 == s2) : " + (s1 == s2)); } } 运行结果如下: s1.equals(s2) : true (s1 == s2) : true 输出结果说明,s1 与 s2 同指向一个 String对象。
先不着急,我们再修改一下上面代码:
public class Main3 { public static void main(String args[]) { String s1 = "hello world"; String s2 = new String("hello world"); System.out.println("s1.equals(s2) : " + s1.equals(s2)); System.out.println("(s1 == s2) : " + (s1 == s2)); } } 运行结果: s1.equals(s2) : true (s1 == s2) : false 输出结果说明,s1 与 s2 不属于同一个String对象。
为什么出现上面这个怪异的问题?
原来,程序在运行的时候会创建一个字符串缓冲池。
当使用 String s2 = “hello world” ,
这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1,将s2引用 s1所引用的 对象 “hello world”。
第二段程序中,使用了 new 操作符,它明白的告诉程序:”我要一个新的!不要旧的!”于是一个新的”hello world” Sting对象被创建在内存中。它们的值相同,但是内存地址不同,一个在池中游泳,另一个在岸边休息。
事情还没完,在看看下面这个例子。
public class Main4 { public static void main(String[] args) { String s1 = "hello world"; String s2 = new String("hello world"); s2 = s2.intern(); System.out.println("s1.equals(s2) : " + s1.equals(s2)); System.out.println("(s1 == s2) : " + (s1 == s2)); } } 运行结果如下: s1.equals(s2) : true (s1 == s2) : true
怎么会这样???
原来,java.lang.String的intern()方法 ,例如 “abc”.intern()方法的返回值还是字符串”abc”,表面上看起来好像这个方法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在”abc”这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会 把”abc”添加到字符串池中,然后再返回它的引用。
相关文章推荐
- JAVA中==和equals方法的区别
- Java equals 方法和 == 的区别
- java中“==”和equals方法有什么区别
- 【高薪就业必备06】 java中"=="和equals方法究竟有什么区别?
- java equals方法和==的区别
- java中equals方法和“==”的区别
- Java中equals方法和==号的区别
- java基础——“==”与equals方法的区别
- java中equals方法和“==”的区别
- Java基础面试题:==和equals方法有何区别?
- JAVA中“==”与equals()方法区别
- Java中关于==和equal的区别 以及equals()方法重写
- Java中"=="与equals()方法的区别
- java中"=="和equals方法究竟有什么区别?
- java中equals方法和“==”的区别:(转)
- Java ==运算符与equals方法的区别及intern方法的正确使用
- JAVA中“==”与equals()方法区别
- Java中equals方法和"==”运算符的区别
- Java中equals方法、==和hashCode的区别
- Java ==运算符与equals方法的区别及intern方法的正确使用