00012.03根父类Object(toString()、getClass()、finalize()、equals和hashCode)

一、什么是根父类

1、Java中规定:如果一个类没有显示声明它的父类,即没有写extends xx,那么这个类就默认继承java.lang,Object

在这里插入图片描述
如上图,我们随便一个类都是继承的Object
类Object是类层次结构的根类,每个类都使用Object作为超类(父类)
2、如何理解根父类
(1)所有对象(包括数组)都实现这个类的方法
换句话说,Object类中声明的方法,所有引用数据类型(包括数组)中都有
在这里插入图片描述

二、为什么需要它,它能做什么

(1)所有对象(包括数组)都实现这个类的方法,换句话说Object类中声明的方法,所有引用数据类型(包括数组)中都有
(2)所有类的对象的实例化过程,都会调用Object的实例初始化方法
(3)所有的对象都可以赋值给Object的变量,或者说Object类型的变量,形参,数组可以接收任意类型的对象。

三、怎么用

用法以及注意点:
在这里插入图片描述

package com.atguigu.test04_Object;

public class TestObject {
	//无参构造
	public TestObject(){
		super();//调用Object的无参构造,或者说是无参的实例化方法<init>()
	}
	//主方法
	public static void main(String[] args) {
		int[]arr=new int[5];
		
		TestObject t=new TestObject();
		
		Object obj =new TestObject();//多态引用
		
		test("hello");//多态引用
		
		Object[] all = new Object[5];//多态数组
		all[0] = new TestObject();//多态引用
		
		Object [] array1 = new TestObject[5];//多态数组,可以这样使用
		//【注意】//Object [] array2 = new int [5];//这样写是不可以的,因为int是基本数据类型
	}
	public static void test(Object obj){
		
	}
}

四、根父类的常用方法

在这里插入图片描述
下面说几个最常用的方法

(1)、toString()

完整来说即是public Stringc toString()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重写后的效果是未重写效果是不一样的,我们建议重写

在这里插入图片描述

代码如下:

/*java.lang.Object类型的方法:
(1)public String toString()
*用于返回对象的信息,类似于我们原来写的getInfo(),建议所有子类重写。
*如果没有重写:返回的字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。
*
*如果你直接打印一个对象,或者用对象与字符串进行拼接,默认情况下会自动调用这个对象的toString()
*如何重写? Alt + Shift  + S  选择Generate toString。。。。
*
*/

package com.atguigu.test04_Object;

public class TestMethod_toString {
	public static void main(String[] args) {
		Employee emp = new Employee("欧浪",24,25000);
		System.out.println("开始啰");
		System.out.println(emp.toString());//输出结果:com.atguigu.test04_Object.Employee@15db9742
		System.out.println(emp.hashCode());//输出结果:366712642(10进制)
	}
}
class  Employee{
	//重写父类toString
	@Override
	public String toString() {
		return "Employee [name=" + name + ", age=" + age + ", salary=" + salary + "]";
	}
	//属性(成员变量)
	private String name;
	private int age;
	private double salary;
	//构造器
	public Employee() {
		super();
	}
	public Employee(String name, int age, double salary) {
		super();
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	//get/set
	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 double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	
}

(2)、getClass

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为int是非引用数据类型(int类型是值类型)

(3)、finalize

在这里插入图片描述
a、什么是 finalize()方法,它有什么用?
java.lang.Object的方法:
protected void finalize()
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器(GC)调用此方法。 即不是程序员手动调用
子类重写 finalize 方法,以配置系统资源或执行其他清除。
b、什么情况下用,怎么用
①某个对象确定要被回收了,比喻成“留临终遗言”
②Java程序员是否无法确定具体哪个时间点会调用
③它是由GC调用的
④每一个对象,finalize()只能被调用一次。
如果某个对象在被GC回收之前复活了,那么再死的时候,就不会调用finalize()
当我们在finalize()方法中又让一个引用指向了当前对象this,那么这个对象就复活。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上代码,我们并没有调用输出的finalize方法,但是gc里面主动帮我们调用了
以上例子中 其实finalize我们一般不需要去重写,只是为了让我们搞懂,在什么时候gc会帮我们调用它(我们比喻成“临终遗言””)
c、常见面试题
面试题:final,finalize,finally的区别?

(4)、equals和hashCode

在这里插入图片描述

equals 和 hashCode为什么一起讲,因为他们本身就经常一起出现,干脆就一起讲了
想看官方说明
在这里插入图片描述
a、hashCode
public int hashCode():返回该对象的哈希码值。支持此方法是为了提高哈希表的性能。
提高哈希表的性能,言外之意就是,对象存到某种格式的时候才有用
哈希码值是用这个对象的信息(属性值),通过某种算法,计算出来的一个int值。就好比我们身份证号码代表一个人的信息。
理想状态下,那么每一个对象都应该有一个唯一的哈希码值,现实中,两个不同的对象,可能它的哈希码值相同。
认为:如果两个对象的哈希码值不同,就可以认为这个两个对象一定不“相等”,但是,如果两个对象的哈希码值相同,我们不能认为这个两个对象就一定“相等”,可能相同,也可能不同。
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。


b、equals
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。
换句话说,如果最终要确定两个对象是否“相等”要依据equals方法。
默认情况下,Object类中实现的equals方法,即如果我们自己写的类,没有重写equals方法的话,那么它的比较是等价于“==”,比较的是对象的“地址值”
在这里插入图片描述
在这里插入图片描述
如果重写会怎么样呢?
我们可以选择进行重写:
(1)当此方法equals被重写时,通常有必要重写 hashCode 方法(意思就是你重写了equals()就要重写hashCode())
为什么?
因为:
Java中规定
①如果两个对象调用equals方法返回true,那么这两个对象的hashCode值必须相同
②如果两个对象的hashCode值不同,那么调用equals方法必须是false
③如果两个对象的hashCode值相同,那么调用equals方法可能true也可能false(怎么理解?)

(2)重写equals方法时,要遵循几个原则
①自反性: x.equals(x)一定true 【即 自己跟自己比较一定是true】
②对称性:x.equals(y) 和y.equals(x)结果一样
③传递性: x.equals(y)是true,y.equals(z)也是true,那么x.equals(z)一定true
④一致性:只要参与equals比较的属性值没有修改过,那么无论何时调用,结果都应该一样
⑤对于任何非空引用值 x,x.equals(null) 都应返回 false【即,你用非空对象和空对象比较一定是false】
乍一看,完了,这么多要求,我们还能重写吗,看起来很复杂!
不用担心
ALT+shift+S
在这里插入图片描述
一选择,hashCode()【注意包括了equals】就写完了,当然你觉得它写的不好,可以选择自己写,但是你自己写算法一定要遵循上面的原则
在这里插入图片描述
那么重写后会怎么样呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
但是不管怎么样,字符型的比较,不管是不是常量,开发当中都一定是用equals去比较

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值