Object类
一、java.lang.Object类
1、Object类是所有Java类的根父类
2、如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
3、Object类中的功能(属性、方法)就具有通用性
- (1)属性:无
- (2)方法:equals() / toString() / getClass() / hashCode() / clone() / finalize() / wait() 、notify() 、 notifyAll()
4、Object 类只声明了一个空参的构造器
面试题:
final、finally、finalize的区别与用法
- final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。
- finally是异常处理语句结构的一部分,表示总是执行。
- finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等
详细版https://www.cnblogs.com/smart-hwt/p/8257330.html
二、== 和 equals的区别
1、== 的使用(是一个运算符)
1、可以使用在基本数据类型和引用数据类型变量中
2、①:如果比较的是基础数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)
②:如果比较的是引用数据类型变量:比较两个对象的保存地址值是否相同,即两个引用是否指向同一个实体。== 符号使用时,必须保证符号左右两边的变量类型一致
2、equals() 方法的使用
1、是一个方法,而非运算符
2、只能适用于引用数据类型
3、Object类中equals()的定义:
public boolean equals(Object obj) {
return (this == obj);
}
说明:Object类中定义的equals()和 == 的所用是相同的:比较两个对象的地址值是否相同,即两个引用是否指向同一个实体
4、像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的“实体内容”是否相同
5、通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的“实体内容”是否相同。那么,我们就需要对Object类中的equals()方法进行重写
覆盖equals方法的时候,必须要遵守它的通用规则
①自反性:对于任何非null的引用值x,x.equals(x)必须返回true
②对称性:对于任何非null的引用值x和y,x.equals(y)为true时,y.equals(x)必须为true
③传递性:对于任何非null的引用值x,y,z,如果x.equals(y) = true,并且y.equals(z) = true,那么x.equals(z) = true
④一致性:对于调用了多少次x.equals(y),返回的结果都是一样的
覆盖equals时,总是要覆盖hashCode
①相等的对象必须具有相等的散列码(hashCode),即如果两个对象根据equals(Object)比较是相等的,那么调用这两个对象的hashCode方法都必须产生同样的整数结果
②如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中的hashCode方法,不要求hashCode得到的值相等
重写equals()方法的例子
package com.test;
import java.util.Objects;
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) {
this.name = name;
this.age = age;
}
}
自动生成复写
//让equals()比较的是内容
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return age == customer.age &&
Objects.equals(name, customer.name);
}
模仿String类型的复写
使用情景:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型
//让equals()比较的是内容
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o instanceof Customer){
Customer cust = (Customer)o;
return this.age == cust.age && this.name.equals(cust.name);
}
return false;
}
instanceof关键字的使用:
a instance A:判断对象a是否是类A的实例。如果是,返回true,否则,返回false
三、toString()的使用
1、当我们输出一个对象的引用时,实际上就是调用当前对象的toString(),格式:运行时类名@十六进制hashCode值。
例如
public static void main(String[] args) {
Customer cust = new Customer("Tom", 21);
System.out.println(cust);//com.test.Customer@1540e19d
System.out.println(cust.toString());//com.test.Customer@1540e19d
}
2、Object类中toString()的定义:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
3、像String、Date、File、包装类等都重写了Object类中的toString()方法。使用在调用对象的toString()时,返回“实体内容”信息
例如
public static void main(String[] args) {
String str = new String("MM");
System.out.println(str);//MM,返回的不是一个Object的toString,也是修改后的toString
}
4、自定义类也可以重写toString()方法,当调用此方法时,返回对象的“实体内容”
四:hashCode()
int hashCode():返回该对象的hashCode值。在默认情况下,Object类的hashCode()方法根据该对象的地址来计算。但很多类都重写了Object类的hashCode()方法,不再根据地址来计算其hashCode()方法值
其他
另外,Object类还提供了wait()、notify()、notifyAll()这几个方法,通过这几个方法可以控制线程的暂停和运行。Object类还提供了一个clone()方法,该方法用于帮助其他对象来实现“自我克隆”,所谓“自我克隆”就是得到一个当前对象的副本,而且二者之间完全隔离。由于该方法使用了protected修饰,因此它只能被子类重写或调用