java.lang.Object #
- Object类是所有Java类的根父类
- 如果在类的声明中未使用
extends关键字指明其父类,则默认父类为java.lang.Object类 - Object类中的功能(方法)具有通用性。
- Object类只声明了一个空参的构造器
registerNatives() #
native方法,让程序主动将本地方法链接到调用方,当Java程序需要调用本地方法时就可以直接调用,而不需要虚拟机再去定位并链接。
getClass() #
getClass()方法返回当前运行时的类Class,即当前调用getClass()方法的对象对应的Class(字节码)实例。
clone() #
clone()方法用于克隆当前对象,克隆分为浅克隆和深克隆。Object类中的clone()方法是浅克隆对象。
浅克隆 #
就是复制值一份,然后赋值给克隆出来的对象,所以当浅克隆基本数据类型时,那么可以实现真正意义上的克隆,但是当浅克隆引用数据类型时,那么就会出现复制地址引用一份,然后赋值给克隆对象,这种克隆仅仅只是克隆复制了一份地址引用,本质上这两个对象操作的还是同一块内存,所以达不到真正意义上的克隆对象。
实现深克隆 #
所以一般需要实现Cloneable接口,并重写clone()方法,当复制的属性是引用数据类型时,进行递归克隆(基本数据类型直接复制一份,引用数据类型递归调用clone()方法),重写完clone()方法才实现真正意义上的克隆。
equals() #
- 是一个方法,而非运算符
- 只能适用于引用数据类型
- Object类中equals()的定义:
public boolean equals(Object obj) { return (this == obj); }
- 说明:Object类中定义的
equals()和==的作用是相同的:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体 - 像String、Date、File、包装类等都重写了Object类中的
equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的实体内容是否相同。 - 通常情况下,我们自定义的类如果使用
equals()的话,也通常是比较两个对象的实体内容是否相同。那么,我们就需要对Object类中的equals()进行重写. - 重写的原则:比较两个对象的实体内容是否相同.
- 如果
equals()方法比较两个对象返回为true,那么两个对象的hashCode一定相同;如果equals()方法比较两个对象返回为false,那么两个对象的hashCode不一定不同 - 换句话说,如果两个对象的
hashCode不同,那么两个对象的equals()一定为false;如果两个对象的hashCode相同,那么两个对象的equals()不一定为true
==和equals()的区别 #
==,是一个比较运算符,既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址equals()的话,它是属于java.lang.Object类里面的方法,如果某个类的equals()没有重写,那么和使用==比较的结果一样;我们可以看到String等类的equals()方法是被重写过的,而且String类在日常开发中用的比较多,久而久之,形成了equals()是比较值的错误观点。- 具体要看自定义类里有没有重写Object的
equals()方法来判断。 - 通常情况下,重写
equals()方法,会比较类中的相应属性是否都相等。
hashCode() #
什么是HashCode #
哈希码(HashCode),并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。
HashCode的作用 #
如果在一个包含很多元素的集合中,查找一个元素,那么使用equals()方法挨个比较,那么会非常的慢。所以引入了哈希算法,哈希算法可以根据元素的某些特征(属性),计算出哈希值(散列值),相同哈希值的作为一组,也就是哈希桶,这个桶里面放着的都是哈希值相同元素。在查找元素的时候,可以很快的确定哈希值,从而找到哈希桶,并且在桶里面找到这个元素。
在java中,例如Hashtable、HashSet、HashMap底层使用了数组+链表的基本存储结构,其中数组存储的就是HashCode并且这个HashCode指向一个链表(类似于哈希桶),链表里面存储的都是HashCode相同的元素
当自定义类没重写hashCode()时,哈希值是根据对象在内存中的地址生成的,所以,hashCode()常会和equals()方法同时重写,确保相等的两个对象拥有相等的hashCode。
重写hashCode()与equals() #
public class Student {
private String name;
private int age;
@Override
public boolean equals(Object o) {
// 首先判断两个实例地址是否相同,同地址肯定是同一元素
if (this == o) return true;
// 判断元素是否为null,并且判断两个实例是否属于同一类
if (o == null || getClass() != o.getClass()) return false;
// 依次比较每一个属性是否相等
Student student = (Student) o;
return age == student.age && name.equals(student.name);
}
@Override
public int hashCode() {
// 调用Objects工具类的方法,计算多个属性共同的HashCode
return Objects.hash(name, age);
}
}
重写equals和hashCode方法 #
public class User {
public String id;
public String name;
public int age;
@Override
public boolean equals(Object obj) {
if(this == obj){
return true;//地址相等
}
if(obj == null){
return false;//非空性检查
}
if(obj instanceof User){
User other = (User) obj;
//需要比较的字段相等,则这两个对象相等
if(this.name.equals(other.name) && this.age == other.age){
return true;
}
}
return false;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + (name == null ? 0 : name.hashCode());
result = 31 * result + (age == null ? 0 : age.hashCode());
return result;
}
}
toString() #
获取实例信息,当使用System.out.println()方法打印一个实例的时候,默认调用的就是toString()方法,toString()如果没有重写,默认实现如下
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
notify() #
用于唤醒因线程同步进入阻塞状态的任意一个线程
notifyAll() #
用于唤醒因线程同步进入阻塞状态的所有线程
wait(timeout) #
native方法,可以让当前正在执行的线程进入阻塞状态,直到其他线程调用notify()或者notifyAll()方法来唤醒这个线程,或者当过了参数timeout毫秒之后,自动从阻塞状态进入就绪状态
wait() #
实际上就是wait(0),也就是阻塞后不会自动进入就绪状态,必须由其他线程调用notify()或者notifyAll()方法唤醒
public final void wait() throws InterruptedException {
wait(0);
}
wait(timeout, nanos) #
比wait(timeout)更精细,支持0-999999的纳秒
finalize() #
当垃圾回收机制(Garbage Collection)确认了一个对象没有被引用时,那么垃圾回收机制就会回收这个对象,并在回收的前一刻这个对象调用finalize()方法,这类似C++中的析构函数
java.util.Objects #
Objects是jdk1.7添加的一个工具类,进行一些常用的检查操作。
equals(a,b) #
可以不用考虑空指针异常,比较两个元素
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
deepEquals(a,b) #
主要用于比较数组的所有元素是否相等
isNull(a) #
判断元素是否为null
nonNull(a) #
判断元素是否不为null
requireNonNull(obj) #
检查元素是否为null,如果为null,则会抛出空指针异常;否则返回元素
requireNonNull(obj,message) #
检查元素是否为null,如果为null,则会抛出空指针异常(自定义异常消息);否则返回元素
requireNonNullElse(obj,defaultObj) #
检查obj是否为null,如果不为null则返回obj;如果为null,则返回defaultObj
hash(Object … val) #
为一系列的输入值生成哈希码,该方法的参数是可变参数。
toString(Object o) #
返回指定对象的字符串形式。如果参数为null,则返回字符串"null"。