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