由equals方法和==引发的思考和验证

一、首先,我们应该了解创建字符串是直接使用双引号还是String构造函数


1、使用双引号



a == b 等于true是因为x和y指向方法区中同一个字符串常量,他们的引用时一样的(==比较的是引用

当相同的字符串常量被多次创建时,只会保存字符串常量的一份副本,这称为“字符串驻留”。在java中,所有编译时字符串常量都是驻留


关系操作符生成的是一个boolean结果,它们计算的是操作数的值之间的关系


对于==,如果作用于基本数据类型的变量,则直接比较其存储的“值”是否相等

如果作用于引用类型的变量,则比较的是所指向的对象的地址

对于equals方法,注意:equals方法不能作用于基本数据类型的变量

如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址

诸如string、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容

(详细区别见下面三详述)




2、使用构造函数




小区别:


                        

(构造函数的字节码文件)                                                      (双引号的字节码文件)


补充说明:


1、《java编程思想》这本书中提到:String对象是不可变的,但不可变性会带来一定的效率问题。为String对象重载的“+”操作符就是一个例子。重载的意思是:一个操作符在应用于特定的类时,被赋予了特殊的意义(用于String的“+”与“+=”是java中仅有的两个重载过的操作符,而java并不允许程序员重载任何操作符)


2、上述代码中,我们可以看到编译器自动引入了java.lang.StringBuilder类。虽然我们的代码中没有使用StringBuilder类,但是编译器却自作主张使用了它,因为它更高效。(将StringBuilder 的实例用于多个线程是不安全的)


3、《java核心技术》中提到:从概念上来说,java字符串就是Unicode字符序列,每个用双引号括起来的字符串都是String类的一个实例。


二、编译器可以让字符串共享


1、String类没有提供用于修改字符串的方法,所以在java文档中将string类对象称为不可变字符串。

《java核心技术》有详细说明:这如同数字3永远是数字3一样,字符串“Hello”永远包含H、e、l、l、o的代码单元序列,而不能修改其中的任何一个字符。


但是 对于String aa = "Hello";可以修改字符串变量aa,让它引用另外一个字符串,这就如同可以将存放3的数值变量改成存放4一样。


2、java的设计者认为共享带来的高效率远远胜过于提取、拼接字符串所带来的低效率。(这里涉及了享元模式)


可以想象将各种字符串存放在公共的存储池中,字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符。


三、equals方法


1、Object类中equals方法




说明:


2、String中的equals方法




(当此方法被重写时,通常有必要重写hashCode 方法,以维护hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码)





3、Integer中的equals方法


     

      




猜你喜欢

转载自blog.csdn.net/Ashes18/article/details/72858939