Java基础1----Object类解析
Java基础1—-Object类解析
1.Object简介
众所周知,Object类是Java所有类的万类之源,所有Java类都是继承之Object类,而默认就直接忽略了extends Object这段代码。
2.Object类的源码
话不多说,源码先贴为敬,源码如下:
1 package java.lang; 2 3 public class Object { 4 //本地方法,通过JNI调用 5 private static native void registerNatives(); 6 static {//对象初始化时调用 7 registerNatives(); 8 } 9 //返回object在运行时的类对象 10 public final native Class<?> getClass(); 11 //获取object对象的hashcode 12 public native int hashCode(); 13 //比较对象的内存地址 14 public boolean equals(Object obj) { 15 return (this == obj); 16 } 17 //本地的clone方法,用于对象的copy 18 protected native Object clone() throws CloneNotSupportedException; 19 //返回对象的字符串 20 public String toString() { 21 return getClass().getName() + "@" + Integer.toHexString(hashCode()); 22 } 23 24 //唤醒等待此对象锁的单个线程 25 public final native void notify(); 26 //唤醒等待此对象锁的所有线程 27 public final native void notifyAll(); 28 //放弃对象锁,等待指定时间 29 public final native void wait(long timeout) throws InterruptedException; 30 31 public final void wait(long timeout, int nanos) throws InterruptedException { 32 if (timeout < 0) { 33 throw new IllegalArgumentException("timeout value is negative"); 34 } 35 36 if (nanos < 0 || nanos > 999999) { 37 throw new IllegalArgumentException( 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() throws InterruptedException { 50 wait(0); 51 } 52 //用于垃圾回收 53 protected void finalize() throws Throwable { } 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 boolean equals(Object obj) { return (this == obj); }
Object类的equals默认和“==”比较结果一样,比较的是两个对象的内存地址是否一致,所以默认obj1.equals(obj2)=true则obj==obj2也为true;
由于比较的是内存地址,所以即使两个对象的值完全一样,返回的也是false;而我们最常用的String类由于重写了equlas方法,所以只要String的值一样就返回true,String的方法如下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof 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; }
可见String的equals方法是将字符串的每个字符挨个比较,只要每个字符都一样则返回true;
和String情况类似,Integer和Long等也重写了equals方法,如Integer的equals方法源码如下:
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }
//TODO
具体需不需要重写equals,视情况而定,建议是不重写;
toString()方法
public String 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() throws InterruptedException { 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) throws InterruptedException { 2 if (timeout < 0) { 3 throw new IllegalArgumentException("timeout value is negative"); 4 } 5 6 if (nanos < 0 || nanos > 999999) { 7 throw new IllegalArgumentException( 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 void main(String[] args){ 2 Integer i = 200; 3 Integer j = 200; 4 System.out.println(i==j);//输出结果为:false 5 }