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     }
posted @ 2018-08-09 22:14  Lucky帅小武  阅读(790)  评论(0编辑  收藏  举报