java的Object类的方法(equals和toString)


导读:文章内容选自尚硅谷,JDK8,采用eclipse开发环境,主要介绍Object类中最常用的两种方法:equals和toString方法。

Object类的特性

  • Object类没有属性
  • Object类只有一个空参的构造器

关于Object类的方法,如下图
在这里插入图片描述
其中的部分方法是有返回值的,比如说getClass()

package com.atguigu.java;

public class ObjectTest {
    
    
	public static void main(String[] args) {
    
    
		Order order = new Order();
		System.out.println(order.getClass());
		System.out.println(order.getClass().getSuperclass());
	}
}

class Order{
    
    
	
}

运行结果为

class com.atguigu.java.Order
class java.lang.Object

equals(Object obj)

equals(Object obj) 是Object类中最常用的方法之一。

比较 运算符== 与 equals() 的区别

运算符== 的运用(针对基本数据类型)

  • 运算符== 两边的对象可以是基本数据类型,也可以是引用数据类型
  • 运算符== 基本数据类型 比较的是左右两边变量的值的大小
  • 运算符== 引用数据类别 比较的是左右两边变量所存放的地址值是否相等
  • 运算符== 使用时,必须保证左右两边变量类型一致(包括了自动类型提升情况),否则编译器报错

比较基本数据类型的值如下

package com.atguigu.java;

public class EqualsTest {
    
    
	public static void main(String[] args) {
    
    
		int i = 10;
		int j = 10;
		System.out.println(i == j);
		double c = 10.0;
		System.out.println(i == c);//自动类型提升
		char c1 = 10;
		System.out.println(i == c1);
		char c2 = 65;
		char c3 = 'A';
		System.out.println(c2 == c3);
//		boolean b = true;
		
//		System.out.println(b == i); //基本数据类型中,不能把boolean和其他类型进行比较,编译器会报错
	}
}

运行结果为

true
true
true
true

ps:基本数据类型中,不能把boolean和其他类型进行比较,编译器会报错,但是布尔型和布尔型之间可以用运算符== 进行比较。

运算符== 的运用(针对引用数据类型)

先创建一个Customer对象

package com.atguigu.java;

public class Customer {
    
    
	private String name;
	private int age;
}

点击Alt+shift+s,打开工具栏中的Source项
点击Generate Getters and Setters,创建了调用私有属性的公用方法,再点击Generate Constructor Using Fields,构造一个空参构造器和带参数的构造器,创建结果如下

package com.atguigu.java;

public class Customer {
    
    
	private String name;
	private int age;
	public String getName() {
    
    
		return name;
	}
	public void setName(String name) {
    
    
		this.name = name;
	}
	public int getAge() {
    
    
		return age;
	}
	public void setAge(int age) {
    
    
		this.age = age;
	}
	public Customer(String name, int age) {
    
    
		super();
		this.name = name;
		this.age = age;
	}
	public Customer() {
    
    
		super();
	}
}

再在EqualsTest中进行测试

		Customer cust1 = new Customer("Tom",21);
		Customer cust2 = new Customer("Tom",21);
		String str1 = new String("atguigu");
		String str2 = new String("atguigu");
		System.out.println(cust1 == cust2);
		System.out.println(str1 == str2);

运行结果都为false,因为运算符==此时比较的是两个栈空间变量的地址值是否相等,这儿new了两个cust对象,指向堆空间的不同地址,故肯定是不相等的。
ps:字符串是引用数据类型的,这儿的str1和str2也是存放的指向字符串常量池的两个地址,故为false。

equals方法的运用

equals方法是对象的方法,在运用之前要先创建一个对象,才能调用方法。而且一般要在子类中重写equals方法。

  • equals()方法仅适用于引用数据类型
  • 如果没有在子类中对equals方法进行重写,equals方法等于用运算符==。
  • 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是 两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。

在EqualsTest类中进行测试,代码如下

		System.out.println(cust1.equals(cust2));
		System.out.println(str1.equals(str2));
		
		Date date1 = new Date(6441316161L);
		Date date2 = new Date(6441316161L);
		System.out.println(date1.equals(date2));

运行结果为

false
true
true

这儿之所以第一个运行结果是false,是因为我们没有在Customer类中重写equals方法,而调用的是Object类中的equals方法,Object类中的equal方法定义为

public boolean equals(Object obj){
    
    
	return (this == obj);
	}

可见,调用Object类中的equals方法等同于运算符==,结果肯定为false

ps:在运行

System.out.println(cust1.equals(cust2));

这儿是一个多态性的应用,因为equals方法定义的形参为Object类型的,这儿我们传入的是Object类的子类,只不过没有重写过equals方法。

运行 System.out.println(str1.equals(str2)); 返回true,是因为我们在字符串类中重写了equals方法,调用的是子类的方法,进行对实体内容而不是地址值的比较。
运行System.out.println(date1.equals(date2)); 返回true同理,不过我们这儿没有自定义一个Date类,需要从java标准库中进行导入,这儿有一个快捷键

ctrl+shift+o

导入java.util.Date

通常情况下用equals方法是要对实体内容进行比较,因此不能用Object的equals方法,必须在子类中重写一个equals方法,这儿我们在Customer对象中重写一个equals方法
代码如下

	@Override
	public boolean equals(Object obj) {
    
    
		if(this == obj){
    
    
			return true;
		}
		if(obj instanceof Customer){
    
    
			Customer cust = (Customer)obj;
			return cust.age == this.age && this.name.equals(cust.name);
		}else{
    
    
			return false;
		}
	}

运行System.out.println(cust1.equals(cust2)); 其结果为true。
ps:手动重写毕竟过于麻烦,在eclipse环境中,点击工具栏中的source或者按Alt+shift+s,在点击Generate harsCode() and equals(),会自动重写一个equals()和hashCode()方法,这儿我们只要equals()就好,代码如下:

//	@Override
//	public int hashCode() {
    
    
//		final int prime = 31;
//		int result = 1;
//		result = prime * result + age;
//		result = prime * result + ((name == null) ? 0 : name.hashCode());
//		return result;
//	}
	@Override
	public boolean equals(Object obj) {
    
    
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Customer other = (Customer) obj;
		if (age != other.age)
			return false;
		if (name == null) {
    
    
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

ps:自动重写的方法相比于手动重写的方法,其代码的健壮性要好,它遵循equals方法的原则
在这里插入图片描述
图片来源自尚硅谷课件PPT

toString()方法的使用

先付上代码,创建一个ToStringTest类

package com.atguigu.java;

public class ToStringTest {
    
    

	
	public static void main(String[] args) {
    
    
		Customer cust1 = new Customer("Tom",21);
		System.out.println(cust1);
		System.out.println(cust1.toString());
	}
}

发现运行结果都为由哈希表算出的虚拟地址值。

com.atguigu.java.Customer@15db9742
com.atguigu.java.Customer@15db9742

说明在执行 System.out.println(cust1.toString()); 的时候,而点击toString方法查看其源代码

 public String toString() {
    
    
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
     }

而在调用System.out.println(cust1); 的时候,参数列表里是对象的引用,这儿是println重载方法的一种,点进println的时候

    public void println(Object x) {
    
    
       String s = String.valueOf(x);
       synchronized (this) {
    
    
           print(s);
           newLine();
       }
   }

然后再点valueOf查看源码

    public static String valueOf(Object obj) {
    
    
       return (obj == null) ? "null" : obj.toString();
   }

发现最后还是调用了toString(),因为我们此时没有重写toString,这儿的toString是Object类中的方法。

与equals方法类似,像String、Date、File、包装类等都重写了Object类中的toString()方法。重写以后,输出的一般为对象的实体内容而非地址值。在ToStringTest类中加入后续代码

   	String str = new String("mm");
   	System.out.println(str);
   	Date date = new Date(3565112656L);
   	System.out.println(date);

运行结果为

mm
Wed Feb 11 14:18:32 CST 1970

输出的是 实体内容 而非地址值,因此像String类型和Date类型,其实是重写了toString方法的。与equals重写类似,在eclipse环境中同样支持自动重写功能。

假如说我们要在Customer类中重写toString方法,仅需在Customer类中打开工具栏中的source或者点击快捷键,再点击Generate toString,最后点击Customer类中的两个属性,就会自动生成打印类中属性的toString方法。(也可以点击Customer类中的方法,会自动生成打印类中方法的toString方法)

	@Override
	public String toString() {
    
    
		return "Customer [name=" + name + ", age=" + age + "]";
	}

此时再次运行

		System.out.println(cust1);
		System.out.println(cust1.toString());

其结果为

Customer [name=Tom, age=21]
Customer [name=Tom, age=21]

即可打印出实体内容中的属性值。

猜你喜欢

转载自blog.csdn.net/Meloneating/article/details/113806664