Object类--所有类的超类(一)

Object类–所有类的超类(一)

Object类是Java中的一个特殊类,它是所有类的父类,是Java类层中的最高层类,Java中的类都直接或间接的继承自java.lang.Object类,所有对象,包括数组,都实现这个类的方法。
在这里插入图片描述
在Java中一个类只要是没有指定它所继承的类,那么它就是直接继承了Object类,即使如果指明了它的超类,那么它也是间接地继承了Object类,包括用户自定义的类。

正因为所有的类都继承自Object类,所以我们在定义一个类的时候不需要使用extends来显示继承Object类。
在这里插入图片描述
Object中有clone()、equals()、finalize()、getClass()、hashCode()、notify()、notifyAll()、toString()、wait()等方法,由于所有的类都继承了Object,所以所有类都有这些方法,也都可以重写这些方法。

getClass()方法

public final Class<?> getClass()

该方法返回此对象的运行时的Class实例,例如:

public class Book{
	private int id;
	private String name;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public static void main(String[] args) {
		Book book1 = new Book();
		Book book2 = new Book();		
		if (book1.getClass() == book2.getClass()) {
			System.out.println("它们是同一个类" + book1.getClass().getSimpleName() + "的对象");
		}else {
			System.out.println("它们不是同一个类的对象");
		}
	}
}

运行结果:
在这里插入图片描述
注意:getClass().getSimpleName()只返回类名,而getClass().getName()返回包名.类名。

equals()方法

我们都知道比较两个String字符串是否相等时要使用equals()方法,不能使用“==”,因为它比较的是两个字符串的引用是否相等。

例如:

public class Test {
	public static void main(String[] args) {
		String str1 = new String("abc");
		String str2 = new String("abc");
		
		System.out.println(str1 == str2);//false
		System.out.println(str1.equals(str2));//true
	}
}

但是Object的equals()方法比较两个对象是否相等,默认比较两个对象的引用地址是否相等,而不是比较对象的实际内容。
例如:

public class Book{
	private int id;
	private String name;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}	
	public static void main(String[] args) {
		Book book1 = new Book();
		Book book2 = new Book();
		
		book1.setId(1);
		book1.setName("java面向对象程序设计");
		book2.setId(1);
		book2.setName("java面向对象程序设计");
		
		System.out.println(book1 == book2);
		System.out.println(book1.equals(book2));
	}
}

运行结果:
在这里插入图片描述
book1和book2是不同的对象,引用地址不一样,所以第一条输出语句输出false,但是book1和book2有着同样的id和name,第二条输出语句也输出false。

Object的equals()方法比较两个对象是否相等,默认比较两个对象的引用地址是否相等,而不是比较对象的实际内容。

String字符串的equals()方法能够比较两个字符串是否相等是因为String类重写了equals()方法。如果我们需要使用equals()来比较对象内容是否相等则需要重写equals()方法。

重写一个高性能的equals()方法可以尝试下面的重写方式:

(1)检测是否引用同一个对象;

(2)检测其中一个是否为null;

(3)检测是否属于同一个类;

(4)将传入的对象转换成相应的类类型变量;

(5)比价实例域;

(6)子类中定义一个equals()方法要先调用父类的equals()方法比较继承自父类的实例域是否相等。

例如:

public class Book{
	private int id;
	private String name;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public boolean equals(Object arg0) {
		// TODO Auto-generated method stub
		if (this == arg0) {
			return true;
		} else if (arg0 == null) {
			return false;
		} else if (this.getClass() != arg0.getClass()) {
			return false;
		} else {
			Book book = (Book) arg0;
			if (this.id == book.id && this.name.equals(book.name)) {
				return true;
			}else {
				return false;
			}
		}
	}
	
	public static void main(String[] args) throws CloneNotSupportedException {
		Book book1 = new Book();
		Book book2 = new Book();
		book1.setId(1);
		book1.setName("java面向对象程序设计");
		book2.setId(1);
		book2.setName("java面向对象程序设计");
		
		if (book1 == book2) {
			System.out.println("它们是同一个对象");
		}else {
			System.out.println("它们是不同的对象");
		}
		
		if (book1.equals(book2)) {
			System.out.println("它们是相等的对象");
		}else {
			System.out.println("它们是不相等的对象");
		}
	}
}

运行结果:
在这里插入图片描述
注意:不能改变复写的equals方法中的参数类型,如果改变了那就不是重写了equals方法,而是重新定义了一个同名的方法。

hashCode()方法

hash code(散列码)是由对象导出的一个整型值。散列码是没有规律的。如果x和y是两个不同的对象,x.hashCode()与y.hashCode()基本上不会相同。

例如我们可以用字符串的hashCode()方法比较字符串对象:

public class Test {
	public static void main(String[] args) {
		String str1 = new String("hello");
		String str2 = new String("world");
		String str3 = new String("hello");
		StringBuffer str4 = new StringBuffer("hello");
		StringBuilder str5 = new StringBuilder("hello");
		
		System.out.println("str1:" + str1.hashCode());
		System.out.println("str2:" + str2.hashCode());
		System.out.println("str3:" + str3.hashCode());
		System.out.println("str4: " + str4.hashCode());
		System.out.println("str5: " + str5.hashCode());
	}
}

在这里插入图片描述
我们可以看到str1和str3有着相同的hash code值,那是因为String类中重写了hashCode()方法,并且String类的hash code值是由内容导出的,即如果两个字符串内容相同,那么他们的hash code就相同。

str4和str5的hash code值都相同,那是因为StringBuffer和StringBuilder没有重写hashCode()方法,它们的散列码是Object类的默认hashCode方法导出的对象存储地址。

注意:两个对象的hash code值相等,两个对象不一定相等;如果两个对象相等,那么他们的hash code值一定相等。

所以我们重写了equals方法后必须要重写hashCode方法,并且要保证x.equals(y)返回true,则x.hashCode() == y.hashCode()。

import java.util.Objects;
public class Book{
	private int id;
	private String name;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public boolean equals(Object arg0) {
		// TODO Auto-generated method stub
		if (this == arg0) {
			return true;
		} else if (arg0 == null) {
			return false;
		} else if (this.getClass() != arg0.getClass()) {
			return false;
		} else {
			Book book = (Book) arg0;
			if (this.id == book.id && this.name.equals(book.name)) {
				return true;
			}else {
				return false;
			}
		}
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(id,name);//调用Objects.hash()方法
	}
	
	public static void main(String[] args) throws CloneNotSupportedException {
		Book book1 = new Book();
		Book book2 = new Book();
		book1.setId(1);
		book1.setName("java面向对象程序设计");
		book2.setId(1);
		book2.setName("java面向对象程序设计");
		
		if (book1 == book2) {
			System.out.println("它们是同一个对象");
		}else {
			System.out.println("它们是不同的对象");
		}
		
		if (book1.equals(book2)) {
			System.out.println("它们是相等的对象");
		}else {
			System.out.println("它们是不相等的对象");
		}
		System.out.println(book1.hashCode());
		System.out.println(book2.hashCode());
	}
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/is_Javaer/article/details/82793036