深入java面向对象一:==和equals详解

简介:

本文从多篇博客笔记融合而来,系转载,非原创,参考:

    1.  http://www.cnblogs.com/e241138/archive/2012/09/16/2687981.html

    2.  http://blog.csdn.net/xiaoya629/article/details/5549159

    3.《疯狂java讲义》

一、 关于==和equals方法

Java中判断变量相等一般使用==运算符和equals方法。

其中,关于“==”,当我们使用==来比较基本数据类型时,比较的是其值,只要他们的值相同,==就可以返回true。当用==比较引用类型时,比较的是的地址,二者是否引用同一个堆内存空间,如果是,则返回true。即便二引用变量引用的堆内存中的内容完全相同,只要是不同的两个堆内存,也只会返回false

而equals是Object中的方法,用来比较留个对象是否相等,程序员可以通过覆写该方法,定义自己的对象比较规则。String类已经覆写了该方法,用于比较字符串序列内容是否相等。

如果我们自定义了某个类,且此类需要进行对像是否相同的比较,那我们需要覆写equals方法,定义自己的比较规则,而不能直接调用Objectequals方法。


二、 ==比较运算符

   ==比较的是两个基本数据类型的值是否相等,或者两个对象的引用地址是否一样。

   如下代码:

public static void main(String args[]) {
        int a = 1000, b = 1000;
        System.out.println(a == b);

        Integer c = 1000, d = 1000;
        System.out.println(c == d);

        Integer e = 100, f = 100;
        System.out.println(e == f);
    }
运行的结果为:true   false   true

原因:

(1)a和b都是基本数据类型,值也相等,所以 a==b 为true

(2)Integer c = 1000 是将一个基本数据类型的值赋给对象的引用。这里涉及到了装箱的概念,

   就是把把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。

   编译器用的是public static Integer valueOf(int i)方法。

    来看下它的源码:  

  public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
    }
        return new Integer(i);
    }
当i的值在[-128,127]之间时,返回的是IntegerCache缓存的对象的已用,否则返回的是新的对象的引用。
因此,c 和 d 是两个不同的对象, e 和 f 是两个相同的对象。
通过调试也可以看到他们的id值也说明了这一点。

所以,c==d 为 false ,e==f 为 true。


三、 equals运算符

equals比较的是两个对象是否相等。由于每个类都是使用Object作为超类的,所以所有对象(包括数组)也实现这个类方法。

对于Object类的equals方法源代码如下:

public boolean equals(Object obj) {
    return (this == obj);
}
可以看到它调用的就是 == 比较运算符。因此下面的代码结果就很容易看出为false了。


覆写equals判断对象是否相同需要注意以下几点:

1. equals的参数类型应该为ObjectObject可以接收一切类型的对象;

2. 接受之可以先通过==进行判断,看二对象应用的地址是否相同,相同则直接返回true;

3.在以上不成立的情况下进行进一步判断。通过instanceof判断此对象是否是此类的实例。同一个类的实例才可以进行比较,不同类的实例自然不会相同。

4.最后对两对象的每个属性的值进行比较,相同则两对象相同,不同则两对象不同。

 

现按以上思路覆写equals方法,代码如下:

class Person
{
	private String name;
	private String idStr;
	public Person(){}
	public Person(String name , String idStr)
	{
		this.name = name;
		this.idStr = idStr;
	}
	//此处省略name和idStr的setter和getter方法。
	//name属性的setter和getter方法
	public void setName(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return this.name;
	}

	//idStr属性的setter和getter方法
	public void setIdStr(String idStr)
	{
		this.idStr = idStr;
	}
	public String getIdStr()
	{
		return this.idStr;
	}
	//重写equals方法,提供自定义的相等标准
	public boolean equals(Object obj)
	{
		// 如果两个对象为同一个对象
		if (this == obj)
			return true;
		//只有当obj是Person对象
		if (obj != null && obj.getClass() == Person.class)
		{
			Person personObj = (Person)obj;
			//并且当前对象的idStr与obj对象的idStr相等才可判断两个对象相等
			if (this.getIdStr().equals(personObj.getIdStr()))
			{
				return true;
			}
		}
		return false;
	}
}
public class OverrideEqualsRight
{
	public static void main(String[] args) 
	{
		Person p1 = new Person("孙悟空" , "12343433433");
		Person p2 = new Person("孙行者" , "12343433433");
		Person p3 = new Person("孙悟饭" , "99933433");
		//p1和p2的idStr相等,所以输出true
		System.out.println("p1和p2是否相等?" 
			+ p1.equals(p2));
		//p2和p3的idStr不相等,所以输出false
		System.out.println("p2和p3是否相等?"
			+ p2.equals(p3));
	}
}


程序输出:


总结:

    1. ==通常用于判断基本类型数据是否相等; 等它用于比较引用类型数据时,表示比较的引用变量所指向的堆内存空间是一致的。

    2. equals方法是Object中的,用于比较两个对象是否相等; 程序员可以通过覆写该方法,定义自己的对象比较规则。




相关文章
|
8天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
9 2
|
1月前
|
存储 Java C++
java中“==”和equals,究竟比的是什么
java中“==”和equals,究竟比的是什么
35 3
java中“==”和equals,究竟比的是什么
|
2月前
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
2月前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
32 4
|
2月前
|
Java
接口和抽象类【Java面向对象知识回顾②】
本文讨论了Java中抽象类和接口的概念与区别。抽象类是不能被实例化的类,可以包含抽象和非抽象方法,常用作其他类的基类。接口是一种纯抽象类型,只包含抽象方法和常量,不能被实例化,且实现接口的类必须实现接口中定义的所有方法。文章还比较了抽象类和接口在实现方式、方法类型、成员变量、构造方法和访问修饰符等方面的不同,并探讨了它们的使用场景。
接口和抽象类【Java面向对象知识回顾②】
|
26天前
|
存储 Java 程序员
Java基础-面向对象
Java基础-面向对象
13 0
|
2月前
|
安全 Java Go
面向对象程序设计语言:Java
Java语言语法和C语言和C++语言很接近,很容易学习和使用,Java丢弃了C++中很少使用的、很难理解的、令人迷惑的特性,Java语言不使用指针,而是引用,并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧
53 2
|
2月前
|
Java 开发者
Java 面向对象
Java 是一种面向对象的编程语言,通过对象与类的概念组织代码和数据。面向对象编程的核心包括类、对象、继承、多态、封装和抽象。类是对象的蓝图,定义了属性和行为;对象则是类的实例。继承允许子类继承父类的属性和方法,增强代码复用性;多态则支持通过相同接口调用不同类型对象的行为,包括方法重载和重写。封装通过公共方法隐藏对象细节,提高安全性;抽象则对对象特征进行提炼,通过抽象类和接口实现。理解这些概念有助于设计高效、可维护的 Java 应用程序。
|
3月前
|
Java 开发者 C++
|
2月前
|
Java 开发者
Java编程之旅:探索面向对象的力量
【9月更文挑战第16天】在编程的世界中,Java以其强大的面向对象编程特性而闻名。本文将带你走进Java的世界,一起探索类与对象的奥秘,学习如何通过封装、继承和多态性构建健壮的软件系统。无论你是初学者还是有经验的开发者,本文都旨在提供实用的代码示例,帮助你提升Java技能。准备好开始这段旅程了吗?让我们启程吧!