欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA中对 “==” 和 equals 的理解

程序员文章站 2024-02-09 17:16:46
...

JAVA中的数据类型分两种:

  • 基本数据类型(byte、int、boolean、char 等等)
  • 引用类型(对象、数据、String)

基本类型比较

  • 使用 == 判断值是否相等

引用类型比较

  • 重写了equals方法,比如String。
    • 第一种情况:使用==比较的是String的引用是否指向了同一块内存。
    • 第二种情况:使用equals比较的是String的引用的对象内用是否相等。
  • 没有重写equals方法,比如User等自定义类
    • ==和equals比较的都是引用是否指向了同一块内存。

String是个较为特殊的包装类型,直接用=“”创建的数据是存放在常量池,且无论数据大小都不会申请空间创建,除非使用new关键字。

如果使用new关键字,会在常量池和堆中都存在一个对象,若有一个相同的对象已经在常量池存在,就只会在堆中创建对象。

		String a1 = new String("abc"); // 在常量池和堆中创建对象(共两个),在栈中创建对象引用(a1)
		String b1 = new String("abc"); // 由于常量池存在相同对象,只在堆中创建对象,在栈中创建对象引用(b1)
		System.out.println(a1 == b1);  // 比较a1和b1的对象引用的指向地址(堆中对象)是否相同	,简单地说就是指向的区域是否相同,false

如果直接赋值,则只会在常量池中创建对象

		String c1 = "abc"; // 在常量池中创建对象,在栈中创建对象引用
		String d1 = "abc"; // 在常量池已有此内容,不再选择创建对象,在栈中创建引用
		System.out.println(c1 == d1); // 判断两个引用是否指向同一区域,true

包装器类型

JVM会自动维护八种基本类型的常量池,int常量池中初始化-128~127的范围,所以当为Integer i=127时,在自动装箱过程中是取自常量池中的数值,而当Integer i=128时,128不在常量池范围内,所以在自动装箱过程中需new 128,所以地址不一样。

		Integer e1 = 122; // 包装器类型在-128~127时,自动装箱取自常量池
		Integer f1 = 122;
		System.out.println(e1 == f1); // 指向同一区域,true
		Integer e2 = 1222; // 包装器类型大于128,所以这一句相当于Interger e2 = new Integer(1222);
		Integer f2 = 1222; // 所以这里就是创建了两个对象
		System.out.println(e2 == f2); // 指向了两个对象所以为false

具体事例

		String a1 = new String("abc"); // 在常量池和堆中创建对象(共两个),在栈中创建对象引用(a1)
		String b1 = new String("abc"); // 由于常量池存在相同对象,只在堆中创建对象,在栈中创建对象引用(b1)
		System.out.println(a1 == b1);  // 比较a1和b1的对象引用的指向地址(堆中对象)是否相同	,简单地说就是指向的区域是否相同
		
		String a2 = new String("abc"); 
		String b2 = new String("abc");
		System.out.println(a2.equalsIgnoreCase(b2)); // 比较a2和b2两个对象的内容是否相等(在堆中分别占有空间)
		
		String c1 = "abc"; // 在常量池中创建对象,在栈中创建对象引用
		String d1 = "abc"; // 在常量池已有此内容,不再选择创建对象,在栈中创建引用
		System.out.println(c1 == d1); // 判断两个引用是否指向同一区域
		
		String c2 = "abc";
		String d2 = "abc";
		System.out.println(c2.equalsIgnoreCase(d2)); // 判断c2和d2内容是否相等
		
		Integer e1 = 122; // 包装器类型在-128~127时,自动装箱取自常量池
		Integer f1 = 122;
		System.out.println(e1 == f1); // 指向同一区域
		
		Integer e2 = 1222; // 包装器类型大于128,所以这一句相当于Interger e2 = new Integer(1222);
		Integer f2 = 1222; // 所以这里就是创建了两个对象
		System.out.println(e2 == f2); // 指向了两个对象所以为false
		
		Integer g1 = 122; // 很明显相同
		Integer h1 = 122;
		System.out.println(g1.equals(h1));
		
		Integer g2 = 1222; // 很明显相同
		Integer h2 = 1222;
		System.out.println(g2.equals(h2));

运行结果:

false
true
true
true
true
false
true
true
相关标签: java