1.Object简介
众所周知,Object类是Java所有类的万类之源,所有Java类都是继承之Object类,而默认就直接忽略了extends Object这段代码。
2.Object类的源码
话不多说,源码先贴为敬,源码如下:
1 packagejava.lang;2
3 public classObject {4 //本地方法,通过JNI调用
5 private static native voidregisterNatives();6 static{//对象初始化时调用7 registerNatives();8 }9 //返回object在运行时的类对象
10 public final native Class>getClass();11 //获取object对象的hashcode
12 public native inthashCode();13 //比较对象的内存地址
14 public booleanequals(Object obj) {15 return (this ==obj);16 }17 //本地的clone方法,用于对象的copy
18 protected native Object clone() throwsCloneNotSupportedException;19 //返回对象的字符串
20 publicString toString() {21 return getClass().getName() + "@" +Integer.toHexString(hashCode());22 }23
24 //唤醒等待此对象锁的单个线程
25 public final native voidnotify();26 //唤醒等待此对象锁的所有线程
27 public final native voidnotifyAll();28 //放弃对象锁,等待指定时间
29 public final native void wait(long timeout) throwsInterruptedException;30
31 public final void wait(long timeout, int nanos) throwsInterruptedException {32 if (timeout < 0) {33 throw new IllegalArgumentException("timeout value is negative");34 }35
36 if (nanos < 0 || nanos > 999999) {37 throw newIllegalArgumentException(38 "nanosecond timeout value out of range");39 }40
41 if (nanos > 0) {42 timeout++;43 }44
45 wait(timeout);46 }47
48
49 public final void wait() throwsInterruptedException {50 wait(0);51 }52 //用于垃圾回收
53 protected void finalize() throwsThrowable { }54 }
3.Object类的方法
Object类方法如下
getClass()方法:
1 public final native Class> getClass();
final类型的本地方法,通过JNI调用,返回对象在运行时的Class对象,如:
User user = new User();
Class c = user.getClass();
返回的是User的Class类对象
hashCode()方法
public native int hashCode();
返回该对象的哈希值,可以重写hashCode方法,但是重写了hashCode一般也需要重写equals方法,必须满足
obj1.equals(obj2)==true,则obj1.hashCode()==obj2.hashCode();但是反过来两个对象的hashCode一直不一定两个对象equals
equals(Object obj)方法
public booleanequals(Object obj) {return (this ==obj);
}
Object类的equals默认和“==”比较结果一样,比较的是两个对象的内存地址是否一致,所以默认obj1.equals(obj2)=true则obj==obj2也为true;
由于比较的是内存地址,所以即使两个对象的值完全一样,返回的也是false;而我们最常用的String类由于重写了equlas方法,所以只要String的值一样就返回true,String的方法如下:
public booleanequals(Object anObject) {if (this ==anObject) {return true;
}if (anObject instanceofString) {
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;
}
可见String的equals方法是将字符串的每个字符挨个比较,只要每个字符都一样则返回true;
和String情况类似,Integer和Long等也重写了equals方法,如Integer的equals方法源码如下:
public booleanequals(Object obj) {if (obj instanceofInteger) {return value ==((Integer)obj).intValue();
}return false;
}
//TODO
具体需不需要重写equals,视情况而定,建议是不重写;
toString()方法
publicString toString() {return getClass().getName() + "@" +Integer.toHexString(hashCode());
}
返回一个字符串,默认有对象的类名+@+对象哈希值的无符号十六进制表示,建议重写;
clone()方法
1 protected native Object clone() throws CloneNotSupportedException;
projected修饰的本地方法,实现了对象的浅复制,只有实现了Cloneable接口的对象才可调用此方法;
notify()方法
public final native void notify();
final类型的本地方法,用于唤醒在等待该对象锁的某个线程
notifyAll()方法
public final native void notifyAll();
final类型的本地方法,用于唤醒在等待该对象锁的全部线程
wait()方法
1 public final void wait() throwsInterruptedException {2 wait(0);3 }
wait(long timeout)方法
1 public final native void wait(long timeout) throws InterruptedException;
wait(long timeout,int nanos)方法
1 public final void wait(long timeout, int nanos) throwsInterruptedException {2 if (timeout < 0) {3 throw new IllegalArgumentException("timeout value is negative");4 }5
6 if (nanos < 0 || nanos > 999999) {7 throw newIllegalArgumentException(8 "nanosecond timeout value out of range");9 }10
11 if (nanos > 0) {12 timeout++;13 }14
15 wait(timeout);16 }
可以看出这三个wait方法最终都是调用了wait(long timeout)方法,这也是个final类型的本地方法;
该方法的作用是让当前线程放弃该对象的对象锁进入等待状态,前提是当前线程已经获取到了该对象的锁。一直等待直到timeout时间到或其他线程调用了该对象的notify()或notifyAll()方法;
finalize()方法
protected void finalize() throws Throwable { }
用于垃圾回收时调用,详情可参看垃圾回收机制;
4.注意事项
1.Integer类和Long类都重写了equals方法,所以比较Integer类型和Long类型的值是否相同是需要使用equals方法,而不建议使用==;
而int和long由于是基本数据类型,没有equals方法,所以比较值相等必须使用==,Integer和Long则不可以,如下例子:
1 public static voidmain(String[] args){2 Integer i = 200;3 Integer j = 200;4 System.out.println(i==j);//输出结果为:false
5 }