Object 所有的java对象都隐式的继承了Object对象,都有Object默认的方法
registerNatives() 底层实现不研究
hashCode() equals(Object obj)
clone() toString()
wait(long TimeOut) notify() notifyAll()
finalize()
一、equals()和hashCode()方法
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj); }
重要特性:
重写equals()方法,就必须重写hashCode()的方法
equals()方法默认是比较对象的地址,使用的是==等值运算符
hashCode()方法对底层是散列表的对象有提升性能的功能
同一个对象(如果该对象没有被修改):那么重复调用hashCode()那么返回的int是相同的!
hashCode()方法默认是由对象的地址转换而来的
equals()方法还有5个默认的原则:
自反性--->调用equals()返回的是true,无论这两个对象谁调用equals()都好,返回的都是true
一致性--->只要对象没有被修改,那么多次调用还是返回对应的结果!
传递性--->x.equals(y)和y.equals(z)都返回true,那么可以得出:x.equals(z)返回true
对称性--->x.equals(y)和y.equals(x)结果应该是相等的。
传入的参数为null,返回的是false
这是String中默认实现的equals()和hashCode()方法
public boolean equals(Object anObject) {
if (this == anObject) { //若是同一对象,则true
return true;
}
if (anObject instanceof String) { //同为String实例
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) { //两个对象长度相同
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) { //比较每一位相同吗
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i]; //计算hashi值的算法
}
hash = h;
}
return h;
}
二、 clone方法
clone方法用于对象的克隆,克隆出的对象是独立的
深拷贝:该对象的成员变量(如果是可变引用)都应该克隆一份
浅拷贝:该对象的成员变量(如果是可变引用)都应该克隆一份
public class Person implements Cloneable {
private Date date;
// 最好修饰成public
@Override
public Object clone() throws CloneNotSupportedException {
// 拷贝Person对象
Person person=(Person) super.clone();
// 将可变的成员变量也拷贝 深拷贝
person.date=(Date) date.clone();
return person;
}
}
三、Protected
protected修饰的类和属性,对于自己、本包和其子类可见,这句话本身是没有错的。但是还需要补充:
对于protected的成员或方法,要分子类和超类是否在同一个包中。与基类不在同一个包中的子类,
只能访问自身从基类继承而来的受保护成员,而不能访问基类实例本身的受保护成员。
四、wait和noyify方法 Java给我们提供让线程之间通信的API。
需要记住的知识点
1、无论是wait、notify还是notifyAll()都需要由 监听器对象(锁对象)来进行调用
2、简单来说:他们都是在同步代码块中调用的,否则会抛出异常!
3、notify()唤醒的是在等待队列的某个线程(不确定会唤醒哪个),notifyAll()唤醒的是等待队列所有线程
4、导致wait()的线程被唤醒可以有4种情况
该线程被中断
wait()时间到了
被notify()唤醒
被notifyAll()唤醒
5、调用wait()的线程会释放掉锁
6、notify方法调用后,被唤醒的线程不会立马获得到锁对象。而是等待notify的synchronized代码块执行完之后才会获得锁对象
二者区别: Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权。
主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。
而Thread.sleep()没有对锁释放
五、finallize方法 垃圾回收器清除对象之前调用 (不很重要)
一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,
所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。
本文参考 Object对象你真理解了吗?