浅谈Java Object类

今天有空来总结一下Java.lang包中的Object类,若有不当请多指教!html

Object类是Java中其余全部类的父类。
Object类位于java.lang包中,java.lang包包含着Java最基础和核心的类,在编译时会自动导入。
Object类没有定义属性,一共有12个方法,具体以下:java

  • registerNatives()
  • clone()
  • getClass()
  • equals(Object obj)
  • hashCode()
  • toString()
  • notify()
  • notifyAll()
  • wait()
  • wait(long timeout)
  • wait(long timeout, int nanos)
  • finalize()

接下来咱们来对这些方法逐个介绍。算法

registerNatives

private static native void registerNatives();
    static {
        registerNatives();
    }

registerNatives函数前面有native关键字修饰,Java中,用native关键字修饰的函数代表该方法的实现并非在Java中去完成, 而是由C/C++去完成,并被编译成了.dll,由Java去调用。方法的具体实现体在dll文件中,对于不一样平台,其具体实现应该有所不一样。多线程

clone

protected native Object clone() throws CloneNotSupportedException;

clone函数返回的是一个引用,指向的是新的clone出来的对象,此对象与原对象分别占用不一样的堆空间。只有实现了Cloneable接口才能够调用该方法,不然抛出CloneNotSupportedException异常。Cloneable接口仅是一个表示接口,接口自己不包含任何方法。函数

clone和copy的区别:

假设如今有一个Person对象,Person person1 =new Person("czy",18);一般会有这样的复制
Person person2=person1,这个时候只是简单了copy了一下reference,person1和person2都指向内存中同一个object,这样person1或者person2的一个操做均可能影响到对方。显然这不是咱们愿意看到的。咱们但愿获得tobby的一个精确拷贝,同时二者互不影响,这时候咱们就可使用Clone来知足咱们的需求。
Person person2=person1.clone(),这时会生成一个新的Person对象,而且和person1具备相同的属性值和方法。性能

getClass

public final native Class<?> getClass();

getClass()也是一个native方法,返回的是此Object对象的类对象/运行时类对象Class<?>。效果与Object.class相同。this

equals

public boolean equals(Object obj) { 
      return (this == obj); 
 }

能够看到Object中的equals方法默认使用==进行比较。线程

==和equals的区别:

在Java中有8种基本数据类型:
  - 浮点型:float(4 byte), double(8 byte)
  - 整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)
  - 字符型: char(2 byte)
  - 布尔型: boolean(JVM规范没有明确规定其所占的空间大小,仅规定其只可以取字面值"true"和"false")
对于这8种基本数据类型的变量,变量直接存储的是“值”,所以在用关系操做符==来进行比较时,比较的就是 “值” 自己。code

而对于非基本数据类型的变量,引用类型的变量存储的并非 “值”自己,而是于其关联的对象在内存中的地址。htm

总结来讲:

  • 对于==,若是做用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;若是做用于引用类型的变量,则比较的是所指向的对象的地址
  • 对于equals方法,若是没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
Java中的约定:重写equals()方法必须重写hasCode()方法。

hashcode

public native int hashCode();

hashCode()方法返回一个整形数值,表示该对象的哈希值。
因为hashCode方法定义在Object类,因此每一个对象都有一个默认的哈希值,其值为对象的存储地址。

hashCode()具备以下约定:

  • 在Java应用程序程序执行期间,对于同一对象屡次调用hashCode()方法时,其返回的哈希码是相同的,前提是没有重写equals()方法。
  • 若是两个对象相等(依据:调用equals()方法),那么这两个对象调用hashCode()返回的哈希码也必须相等;
  • 反之,两个对象调用hasCode()返回的哈希码相等,这两个对象不必定相等。

hashCode()方法主要用于加强哈希表的性能。
以集合类中,以Set为例,当新加一个对象时,须要判断现有集合中是否已经存在与此对象相等的对象。
若是没有hashCode()方法,须要将Set进行一次遍历,并逐一用equals()方法判断两个对象是否相等,此种算法时间复杂度为o(n)。
经过借助于hasCode方法,先计算出即将新加入对象的哈希码,而后根据哈希算法计算出此对象的位置,直接判断此位置上是否已有对象便可。

toString

public String toString() { 
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

toString()方法返回该对象的字符串表示。

getClass().getName():返回类对象的名称
Integer.toHexString(hashCode()):以对象的哈希码为实参,以16进制无符号整数形式返回此哈希码的字符串表示形式。
toString()是由对象的类型和其哈希码惟一肯定,同一类型但不相等的两个对象分别调用toString()方法返回的结果可能相同。

wait/notify/notifyAll

这几个方法主要用于java多线程之间的协做。
在Object类中有三个wait的重载方法:wait() 、wait(long timeout)、wait(long timeout, int nanos)

wait():调用此方法所在的当前线程等待,直到在其余线程上调用此方法的的notify()/notifyAll()方法。
wait(long timeout)/wait(long timeout, int nanos):调用此方法所在的当前线程等待,直到在其余线程上调用此方法的notisfy()/notisfyAll()方法,或超过指定的超时时间。
notify()/notifyAll():唤醒在此对象监视器上等待的随机单个线程/全部线程。

既然是做用于多线程中,为何倒是Object这个基类所具备的方法?
缘由在于理论上任何对象均可以视为线程同步中的监听器,且wait(...)/notify()|notifyAll()方法只能在同步代码块中才能使用。

finalize

protected void finalize() throws Throwable { }

finalize方法主要与Java垃圾回收机制有关。

Object中定义finalize方法代表Java中每个对象都将具备finalize这种行为, 其具体调用时机在:JVM准备对此对对象所占用的内存空间进行垃圾回收前,将被调用。由此能够看出,此方法并非由咱们主动去调用的。

参考

https://www.cnblogs.com/lwbqqyumidi/p/3693015.html

相关文章
相关标签/搜索