Object类
所有类型都隐式的派生于java.lang.Object类,其主要用于两个目的:
- 使用Object引用绑定任何数据类型的对象;
- Object类型执行许多基本的一般用途的方法,包括clone(),equals(), finalize(), hashCode(), getClass(), toString(), notify(), notifyAll()和wait().
clone方法
保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异常。
getClass方法
final方法,获得运行时类型,得到一个Class对象
public static void main(String[] args){
LittlePie littlePie = new LittlePie();
System.out.println(littlePie.getClass());
Class c = littlePie.getClass();
Pie pie = null;
try {
pie = (Pie) c.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(pie.getClass());
System.out.println(littlePie instanceof LittlePie);
System.out.println(pie instanceof LittlePie);
System.out.println(littlePie instanceof Pie);
System.out.println(littlePie instanceof Object);
}
static class Pie {
}
static class LittlePie extends Pie{
}
输出:
class Main$LittlePie
class Main$LittlePie
true
true
true
true
toString方法
toString返回一个字符串,该方法用得比较多,一般子类都有覆盖。
public static void main(String[] args){
Pie pie = new Pie();
System.out.println(pie.toString());
}
static class Pie {
@Override
public String toString() {
return "i am pie->" + super.toString();
}
}
输出:i am pie->Main$Pie@4554617c
finalize方法
一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。
public static void main(String[] args){
Pie pie = new Pie();
pie = null;
System.gc();
}
static class Pie {
@Override
protected void finalize() throws Throwable {
System.out.println("我要被回收了");
}
}
输出:我要被回收了
equals方法
该方法是非常重要的一个方法。一般equals和==是不一样的,但是在Object中两者是一样的。子类一般都要重写这个方法。
java重写equals方法需要注意的几点
Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例
public static void main(String[] args){
Pie pie = new Pie();
Pie pie1 = new Pie();
System.out.println(pie == pie1);
}
static class Pie {
@Override
public boolean equals(Object obj) {
return true;
}
}
输出:false
hashcode方法
该方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。这个方法在一些具有哈希功能的Collection中用到。
一般必须满足obj1.equals(obj2)==true。可以推出obj1.hashCode()==obj2.hashCode(),但是hashCode相等不一定就满足equals。不过为了提高效率,应该尽量使上面两个条件接近等价。
如果不重写hashcode(),在HashSet中添加两个equals的对象,会将两个对象都加入进去。
public static void main(String[] args){
Pie pie = new Pie();
Pie pie1 = pie;
Pie pie2 = new Pie();
System.out.println(pie.hashCode() + " " + pie1.hashCode() + " " + pie2.hashCode());
}
static class Pie {
@Override
public int hashCode() {
return super.hashCode();
}
}
输出:1163157884 1163157884 1956725890
notify,notifyAll,wait
wait,notify,notifyAll 是定义在Object类的实例方法,用于控制线程状态。
三个方法都必须在synchronized 同步关键字所限定的作用域中调用,否则会报错java.lang.IllegalMonitorStateException ,意思是因为没有同步,所以线程对对象锁的状态是不确定的,不能调用这些方法。
wait 表示持有对象锁的线程A准备释放对象锁权限,释放cpu资源并进入等待。
notify 表示持有对象锁的线程A准备释放对象锁权限,通知jvm唤醒某个竞争该对象锁的线程X。线程A synchronized 代码作用域结束后,线程X直接获得对象锁权限,其他竞争线程继续等待(即使线程X同步完毕,释放对象锁,其他竞争线程仍然等待,直至有新的notify ,notifyAll被调用)。
notifyAll 表示持有对象锁的线程A准备释放对象锁权限,通知jvm唤醒所有竞争该对象锁的线程,线程A synchronized 代码作用域结束后,jvm通过算法将对象锁权限指派给某个线程X,所有被唤醒的线程不再等待。线程X synchronized 代码作用域结束后,之前所有被唤醒的线程都有可能获得该对象锁权限,这个由JVM算法决定。