日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java.lang包—对象基类Object

發(fā)布時(shí)間:2024/4/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java.lang包—对象基类Object 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文作者:Boblim

原文地址:Java:Object類詳解

目錄

一、上帝類

二、Object的類方法

三、常見面試題


Java的一些特性會讓初學(xué)者感到困惑,但在有經(jīng)驗(yàn)的開發(fā)者眼中,卻是合情合理的。例如,新手可能不會理解Object類。這篇文章分成三個部分講跟Object類及其方法有關(guān)的問題。

一、上帝類

什么是Object類?

Object類存儲在java.lang包中,是所有java類(Object類除外)的終極父類。當(dāng)然,數(shù)組也繼承了Object類。然而,接口是不繼承Object類的,原因在這里指出:Section 9.6.3.4 of the Java Language Specification

?Object類中聲明了以下函數(shù),java的任何類都繼承了這些函數(shù),并且可以覆蓋不被final修飾的函數(shù)。例如,沒有final修飾的toString()函數(shù)可以被覆蓋,但是final wait()函數(shù)就不行。我會在下文中詳細(xì)說明這些函數(shù)。

protected Object clone() boolean equals(Object obj) protected void finalize() Class< > getClass() int hashCode() String toString() void wait() void wait(long timeout) void wait(long timeout, int nanos) void notify() void notifyAll()

可以聲明要“繼承Object類”嗎?

可以。Object 類可以顯示繼承,也可以隱式繼承;在代碼中明確地寫出繼承Object類沒有語法錯誤。即以下兩種寫法都正確:

importjava.lang.Object; //明確的繼承Object類 public class Employee extends Object {public static void main(String[] args) {} } //默認(rèn)繼承Object類 public class Employee{private String name;publicstaticvoidmain(String[] args){} }

二、Object的類方法

1、關(guān)于克隆函數(shù)clone()

Java基礎(chǔ)—復(fù)制之深拷貝與淺拷貝

2、關(guān)于wait()/notify()/?notifyAll()

Java并發(fā)編程—線程間協(xié)作方式wait()/notify()/notifyAll()原理分析

3、關(guān)于比較函數(shù)equals(Object obj)

什么時(shí)候需要重寫equals()?我們知道每一個java類都繼承自O(shè)bject類,equals()是Object類中提供的方法之一。那么,讓我們先來看看Object#equals()在Java中的原代碼:

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

可以看出,只有當(dāng)一個實(shí)例等于它本身的時(shí)候,equals()才會返回true值。通俗地說,此時(shí)比較的是兩個引用是否指向內(nèi)存中的同一個對象,也可以稱做是否實(shí)例相等。而我們在使用equals()來比較兩個指向值對象的引用的時(shí)候,往往希望知道它們邏輯上是否相等,而不是它們是否指向同一個對象。在這樣的情況下, 如果超類也沒有重寫equals()以實(shí)現(xiàn)期望的行為,這時(shí)我們就需要重寫equals方法。而且這樣做也使得這個類的實(shí)例可以被用做映射表(map)的鍵,或者集合(set)的元素,并使映射表或者集合表現(xiàn)出預(yù)期的行為。Object類提供的equals方法只是一個很簡單的,不能適應(yīng)應(yīng)用程序有特殊要求的情況。比如網(wǎng)絡(luò)對象,帶有volatile屬性的對象,或是帶有多層子對象的復(fù)合對象,等等,是不能像String一類的對象進(jìn)行簡單比較的,所以提供了這樣一個機(jī)制,就像serializable接口一樣,既有默認(rèn)的序列化方法,也提供了程序自己定制,覆蓋默認(rèn)方式的可能性。Object僅僅提供了一個對引用的比較,如果兩個引用不是同一個那就返回false,這是無法滿足大多數(shù)對象比較的需要的,所以要覆蓋。

怎樣重寫equals()方法?重寫equals()方法看起來非常簡單,但是有許多改寫的方式會導(dǎo)致錯誤,并且后果非常嚴(yán)重。要想正確改寫equals()方法,你必須要遵守它的通用約定。下面是約定的內(nèi)容,來自java.lang.Object的規(guī)范:

equals方法實(shí)現(xiàn)了等價(jià)關(guān)系(equivalence relation):

  • 1. 自反性:對于任意的引用值x,x.equals(x)一定為true。
  • 2. 對稱性:對于任意的引用值x 和 y,當(dāng)x.equals(y)返回true時(shí),y.equals(x)也一定返回true。
  • 3. 傳遞性:對于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也一定返回true。
  • 4. 一致性:對于任意的引用值x 和 y,如果用于equals比較的對象信息沒有被修改,多次調(diào)用x.equals(y)要么一致地返回true,要么一致地返回false。
  • 5. 非空性:對于任意的非空引用值x,x.equals(null)一定返回false。

接下來我們通過實(shí)例來理解上面的約定。我們首先以一個簡單的非可變的二維點(diǎn)類作為開始:

public class Point{private final int x;private final int y;public Point(int x, int y){this.x = x;this.y = y;}public boolean equals(Object o){if(!(o instanceof Point))return false;Point p = (Point)o;return p.x == x && p.y == y;}}

假設(shè)你想要擴(kuò)展這個類,為一個點(diǎn)增加顏色信息:

public class ColorPoint extends Point{private Color color;public ColorPoint(int x, int y, Color color){super(x, y);this.color = color;}//override equasl()public boolean equals(Object o){if(!(o instanceof ColorPoint))return false;ColorPoint cp = (ColorPoint)o;return super.equals(o) && cp.color==color;} }

我們重寫了equals方法,只有當(dāng)實(shí)參是另一個有色點(diǎn),并且具有同樣的位置和顏色的時(shí)候,它才返回true。可這個方法的問題在于,你在比較一個普通點(diǎn)和一個有色點(diǎn),以及反過來的情形的時(shí)候,可能會得到不同的結(jié)果:

public static void main(String[] args){Point p = new Point(1, 2);ColorPoint cp = new ColorPoint(1, 2, Color.RED);System.out.println(p.equals(cp));System.out.println(cp.eqauls(p)); }

運(yùn)行結(jié)果:
true??
false

這樣的結(jié)果顯然違反了對稱性,你可以做這樣的嘗試來修正這個問題:讓ColorPoint.equals在進(jìn)行“混合比較”的時(shí)候忽略顏色信息:

public boolean equals(Object o){if(!(o instanceof Point))return false;//如果o是一個普通點(diǎn),就忽略顏色信息if(!(o instanceof ColorPoint))return o.equals(this);//如果o是一個有色點(diǎn),就做完整的比較ColorPoint cp = (ColorPoint)o;return super.equals(o) && cp.color==color; }

這種方法的結(jié)果會怎樣呢?讓我們先來測試一下:

public static void main(String[] args){ColorPoint p1 = new ColorPoint(1, 2, Color.RED);Point p2 = new Point(1, 2);ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);System.out.println(p1.equals(p2));System.out.println(p2.equals(p1));System.out.println(p2.equals(p3));System.out.println(p1.eqauls(p3)); }

運(yùn)行結(jié)果:
true
true
true
false

這種方法確實(shí)提供了對稱性,但是卻犧牲了傳遞性(按照約定,p1.equals(p2)和p2.eqauals(p3)都返回true,p1.equals(p3)也應(yīng)返回true)。要怎么解決呢?事實(shí)上,這是面向?qū)ο笳Z言中關(guān)于等價(jià)關(guān)系的一個基本問題。要想在擴(kuò)展一個可實(shí)例化的類的同時(shí),既要增加新的特征,同時(shí)還要保留equals約定,沒有一個簡單的辦法可以做到這一點(diǎn)。新的解決辦法就是不再讓ColorPoint擴(kuò)展Point,而是在ColorPoint中加入一個私有的Point域,以及一個公有的視圖(view)方法

public class ColorPoint{private Point point;private Color color;public ColorPoint(int x, int y, Color color){point = new Point(x, y);this.color = color;}//返回一個與該有色點(diǎn)在同一位置上的普通Point對象public Point asPoint(){return point;}public boolean equals(Object o){if(o == this)return true;if(!(o instanceof ColorPoint))return false;ColorPoint cp = (ColorPoint)o;return cp.point.equals(point)&&cp.color.equals(color);} }

還有另外一個解決的辦法就是把Point設(shè)計(jì)成一個抽象的類(abstract class),這樣你就可以在該抽象類的子類中增加新的特征,而不會違反equals約定。因?yàn)槌橄箢悷o法創(chuàng)建類的實(shí)例,那么前面所述的種種問題都不會發(fā)生。

重寫equals方法的要點(diǎn):

  • 1. 使用==操作符檢查“實(shí)參是否為指向?qū)ο蟮囊粋€引用”。
  • 2. 使用instanceof操作符檢查“實(shí)參是否為正確的類型”。
  • 3. 把實(shí)參轉(zhuǎn)換到正確的類型。
  • 4. 對于該類中每一個“關(guān)鍵”域,檢查實(shí)參中的域與當(dāng)前對象中對應(yīng)的域值是否匹配。對于既不是float也不是double類型的基本類型的域,可以使用==操作符進(jìn)行比較;對于對象引用類型的域,可以遞歸地調(diào)用所引用的對象的equals方法;對于float類型的域,先使用Float.floatToIntBits轉(zhuǎn)換成int類型的值,然后使用==操作符比較int類型的值;對于double類型的域,先使用Double.doubleToLongBits轉(zhuǎn)換成long類型的值,然后使用==操作符比較long類型的值。
  • 5. 當(dāng)你編寫完成了equals方法之后,應(yīng)該問自己三個問題:它是否是對稱的、傳遞的、一致的?(其他兩個特性通常會自行滿足)如果答案是否定的,那么請找到這些特性未能滿足的原因,再修改equals方法的代碼。

三、常見面試題

1、寫出java.lang.Object類的六個常用方法?Object類中的各個方法有什么作用?

這是一個非常常見的問題,用來確定你對基礎(chǔ)知識的熟悉程度。

2、

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的java.lang包—对象基类Object的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。