比较String对象的两种初始化方式
在java中, String对象的初始化方式有两种:一种是使用字符串变量, 一种是使用new关键字. 而对于字符串的比较也有两种方式: 一种是使用"=="符号, 一种是使用equals方式, 以下是实际中使用的结果:
public static void main(String[] args){ String a = "123"; System.out.println((a == "123") + "," + (a.equals("123"))); // true,true String b = new String("123"); System.out.println((b == "123") + "," + (b.equals("123"))); // false,true }
发现:
对于使用"=="进行对象的比较返回的结果是不一样的, 为什么呢?
首先, 了解一下变量在内存中如何保存:

由上图, 基本数据类型的变量保存在变量区, 而构造数据类型的变量保存在堆区, 两者均将内存中内容保存地址存储在栈中与变量名对应.
其次, "=="和"equals"本质上都是比较地址引用, 只是某些类重写equals达到比较内容的目的(比如String类)
所以, 对于String对象来说, 不同的初始化方式会使用不同的变量机制, 使用变量直接初始化对象时两种比较方式的结果相同
拓展:
对于String对象存在这样的现象, 那个对于Integer/Double呢?
Integer c = 10; System.out.println((c == 10) + "," + (c.equals(10))); // true,true Integer d = new Integer(10); System.out.println((d == 10) + "," + (d.equals(10))); // true,true Double e = 20d; System.out.println((e == 20d) + "," + (e.equals(20d))); // true,true // System.out.println((e == 20) + "," + (e.equals(20))); // true,false Double f = new Double(20d); System.out.println((f == 20d) + "," + (f.equals(20d))); // true,true
结论是: 两种初始化方式的两种比较方式的结果都是true, 但也有特殊的情况存在(注掉的一行), 原因是"=="进行数值和地址的比较,而equals进行内容的比较.
对象间的比较
#java.lang.Object
1 public boolean equals(Object obj) { 2 return (this == obj); 3 }
由此可知,对象间的“==”其实是类似地址的比较,而equal在不进行重写的情况下同“==”一致
最终结论
1、对象的equal比较在不被重写的情况下与等号比较一致,属于类似地址的比较;
2、基本数据类型对象可以使用数值直接初始化,对象地址指向变量区,等号的比较为字符的比较,对于数值不考虑其数据类型,如new Double(20d)==20为true;
而equals由于被重写而异于等号比较。如:java.lang.Double,在比较对象非Double对象时均结果为false。
1 public boolean equals(Object obj) { 2 return (obj instanceof Double) 3 && (doubleToLongBits(((Double)obj).value) == 4 doubleToLongBits(value)); 5 }
基本数据类对象的一般类对象的等号比较和equals比较一致,规则同1。
----------------------------------
浙公网安备 33010602011771号