11. ==和equals方法 & 常量池

一、使用==来判断两个变量是否相等

1. 如果两个变量是基本类型变量,且都是数值类型,则只要两个变量的值相等,就将返回true

2. 如果两个变量是引用类型变量,则只有它们指向同一个对象时,才返回true

		// ex1:基本类型
		int it = 65;
		float fl = 65.0f;
		char ch = 'A';

		boolean bl1 = (it == fl);		// true
		boolean bl2 = (it == ch);		// true

		// ex2:引用类型
		String str1 = new String("Hello");
		String str2 = new String("Hello");

		boolean bl3 = (str1 == str2);	// false

注:str1和str2都是引用类型变量,它们分别指向两个通过new创建的String对象,因此它们不相等。

 

二、使用equals方法来判断两个变量是否相等

1. equals()是Object类提供的一个实例方法,因此所有引用变量都可调用该方法来判断是否与其他引用变量相等

2. Object类提供的equals()同样要求两个引用变量指向同一个对象时才返回true,因此各子类可重写该方法来实现所需的判断标准

  • 如String类中已经重写了equals(),其判断标准是只要两个字符串所包含的字符序列相同,就返回true
		// ex:使用String类重写的equals方法来判断
		String str1 = new String("Hello");
		String str2 = new String("Hello");

		boolean bl = str1.equals(str2);		// true

3. 正确地重写equals()应满足下列条件

  • 自反性:对任意x,x.equals(x)一定返回true
  • 对称性:对任意x和y,如果y.equals(x)返回true,则x.equals(y)也返回true
  • 传递性:对任意x, y, z,如果x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)一定返回true
  • 一致性:对任意x和y,如果对象中用于等价比较的信息没有改变,那么无论调用x.equals(y)多少次,返回的结果应保持一致
  • 对任何不是null的x,x.equals(null)一定返回false

 

三、常量池

1. 当Java程序直接使用形如"Hello"的字符串直接量(包括可以在编译时就计算出来的字符串值,如"Hel" + "lo")时,JVM将会使用常量池来管理这些字符串

2. 当Java程序使用new String("Hello")时,JVM会先使用常量池来管理"Hello"直接量,再调用String类的构造器来创建一个新的String对象,新创建的String对象被保存在堆内存中,换句话说,new String("Hello")一共产生了两个字符串对象

常量池专门用于管理在编译时被确定并被保存在已编译的.class文件中的一些数据,它包括了关于类、方法、接口中的常量,还包括字符串常量。

		// s1直接引用常量池中的"我爱China"
		String s1 = "我爱China";
		String s2 = "我爱";
		String s3 = "China";

		// s4后面的字符串值可以在编译时就确定下来
		// s4直接引用常量池中的"我爱China"
		String s4 = "我爱" + "China";
		// s5和s4是一样的
		String s5 = "我" + "爱" + "China";

		// s6后面的字符串值不能在编译时就确定下来
		// s6不能引用常量池中的"我爱China"
		String s6 = s2 + s3;

		// 使用new调用构造器将会创建一个新的String对象
		// s7引用堆内存中新创建的String对象
		String s7 = new String("我爱China");

		boolean bl1 = (s1 == s4);		// true
		boolean bl2 = (s1 == s5);		// true
		boolean bl3 = (s1 == s6);		// false
		boolean bl4 = (s1 == s7);		// false
  • JVM常量池保证相同的字符串直接量只有一个,不会产生多个副本,因此s1、s4、s5都将引用常量池中的同一个字符串对象
  • 使用new String()创建的字符串对象是运行时创建出来的,它被保存在运行时内存区(即堆内存)内,不会放入常量池中

 

posted @ 2019-06-10 15:52  GGBeng  阅读(357)  评论(0编辑  收藏  举报