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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

使用所有对象共有的方法

發(fā)布時(shí)間:2023/12/3 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用所有对象共有的方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文是我們名為“ 高級(jí)Java ”的學(xué)院課程的一部分。

本課程旨在幫助您最有效地使用Java。 它討論了高級(jí)主題,包括對(duì)象創(chuàng)建,并發(fā),序列化,反射等。 它將指導(dǎo)您完成Java掌握的旅程! 在這里查看 !

目錄

1.簡(jiǎn)介 2.方法equals和hashCode 3.方法toString 4.方法克隆 5.方法等于和==運(yùn)算符 6.有用的助手類 7.下載源代碼 8.接下來(lái)

1.簡(jiǎn)介

從本教程的第1部分“ 如何創(chuàng)建和銷毀對(duì)象”中 ,我們已經(jīng)知道Java是一種面向?qū)ο蟮恼Z(yǔ)言(但是,不是純粹的面向?qū)ο蟮恼Z(yǔ)言)。 在Java類層次結(jié)構(gòu)的頂部是Object類,Java中的每個(gè)類都隱式地繼承自它。 因此,所有類都繼承Object類中聲明的方法集,最重要的是以下方法:

方法 描述
protected Object clone() 創(chuàng)建并返回此對(duì)象的副本。
protected void finalize() 當(dāng)垃圾回收確定不再有對(duì)該對(duì)象的引用時(shí),由垃圾回收器在對(duì)象上調(diào)用。 我們已經(jīng)在本教程的第1部分“ 如何創(chuàng)建和銷毀對(duì)象”中討論了終結(jié)器。
boolean equals(Object obj) 指示其他某個(gè)對(duì)象是否與此對(duì)象“相等”。
int hashCode() 返回對(duì)象的哈希碼值。
String toString() 返回對(duì)象的字符串表示形式。
void notify() 喚醒正在此對(duì)象的監(jiān)視器上等待的單個(gè)線程。 我們將在本教程的第9部分 并發(fā)最佳實(shí)踐中討論此方法。
void notifyAll() 喚醒正在此對(duì)象的監(jiān)視器上等待的所有線程。 我們將在本教程的第9部分 并發(fā)最佳實(shí)踐中討論此方法。
void wait()

void wait(long timeout)

void wait(long timeout, int nanos)

使當(dāng)前線程等待,直到另一個(gè)線程為此對(duì)象調(diào)用notify()方法或notifyAll()方法。 我們將在本教程的第9部分 并發(fā)最佳實(shí)踐中討論這些方法。

表格1

在本教程的這一部分中,我們將介紹equals , hashCode , toString和clone方法,它們的用法以及需要牢記的重要約束。

2.方法equals和hashCode

默認(rèn)情況下,Java中的任何兩個(gè)對(duì)象引用(或類實(shí)例引用)僅在它們引用相同的內(nèi)存位置時(shí)才相等(引用相等)。 但是Java允許類通過(guò)重寫(xiě)Object類的equals()方法來(lái)定義自己的相等性規(guī)則。 聽(tīng)起來(lái)像一個(gè)強(qiáng)大的概念,但是正確的equals()方法實(shí)現(xiàn)應(yīng)符合一組規(guī)則并滿足以下約束:

  • 反身的 。 對(duì)象x必須等于自身,并且equals(x)必須返回true
  • 對(duì)稱的 。 如果equals(y)返回true,y.equals(x)也必須返回true
  • 傳遞的 。 如果equals(y)返回true,y.equals(z)返回true ,則x.equals(z)也必須返回true
  • 一致 。 除非修改用于相等比較的任何屬性,否則多次調(diào)用equals()方法必須得到相同的值。
  • 等于Nullequals(null)的結(jié)果必須始終為false

不幸的是,Java編譯器無(wú)法在編譯過(guò)程中強(qiáng)制執(zhí)行這些約束。 但是,不遵循這些規(guī)則可能會(huì)導(dǎo)致非常怪異且難以解決問(wèn)題。 一般建議是這樣的:如果您打算編寫(xiě)自己的equals()方法實(shí)現(xiàn),請(qǐng)?jiān)趯?shí)際需要時(shí)三思而后行。 現(xiàn)在,有了所有這些規(guī)則,讓我們?yōu)镻erson類編寫(xiě)一個(gè)equals()方法的簡(jiǎn)單實(shí)現(xiàn)。

package com.javacodegeeks.advanced.objects;public class Person {private final String firstName;private final String lastName;private final String email;public Person( final String firstName, final String lastName, final String email ) {this.firstName = firstName;this.lastName = lastName;this.email = email;}public String getEmail() {return email;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}// Step 0: Please add the @Override annotation, it will ensure that your// intention is to change the default implementation.@Overridepublic boolean equals( Object obj ) {// Step 1: Check if the 'obj' is nullif ( obj == null ) {return false;}// Step 2: Check if the 'obj' is pointing to the this instanceif ( this == obj ) {return true;}// Step 3: Check classes equality. Note of caution here: please do not use the // 'instanceof' operator unless class is declared as final. It may cause // an issues within class hierarchies.if ( getClass() != obj.getClass() ) {return false;}// Step 4: Check individual fields equalityfinal Person other = (Person) obj;if ( email == null ) {if ( other.email != null ) {return false;} } else if( !email.equals( other.email ) ) {return false;}if ( firstName == null ) {if ( other.firstName != null ) {return false;} } else if ( !firstName.equals( other.firstName ) ) {return false;}if ( lastName == null ) {if ( other.lastName != null ) {return false;}} else if ( !lastName.equals( other.lastName ) ) {return false;}return true;} }

并非偶然的是,本節(jié)的標(biāo)題中還包含hashCode()方法。 最后要記住的規(guī)則是:每當(dāng)您重寫(xiě)equals()方法時(shí),也始終要重寫(xiě)hashCode()方法。 如果對(duì)于任何兩個(gè)對(duì)象, equals()方法返回true ,則這兩個(gè)對(duì)象中的每個(gè)對(duì)象的hashCode()方法必須返回相同的整數(shù)值(但是相反的語(yǔ)句不那么嚴(yán)格:如果對(duì)于任何兩個(gè)對(duì)象, equals()方法返回false ,則這兩個(gè)對(duì)象中的每個(gè)對(duì)象的hashCode()方法都可能會(huì)或可能不會(huì)返回相同的整數(shù)值)。 讓我們看一下Person類的hashCode()方法。

// Please add the @Override annotation, it will ensure that your // intention is to change the default implementation. @Override public int hashCode() {final int prime = 31;int result = 1;result = prime * result + ( ( email == null ) ? 0 : email.hashCode() );result = prime * result + ( ( firstName == null ) ? 0 : firstName.hashCode() );result = prime * result + ( ( lastName == null ) ? 0 : lastName.hashCode() );return result; }

為了避免意外,請(qǐng)盡可能在實(shí)現(xiàn)equals()和hashCode()同時(shí)嘗試使用final字段。 這將確保這些方法的行為不會(huì)受到字段更改的影響(但是,在實(shí)際項(xiàng)目中,并非總是可能的)。

最后,始終確保在equals()和hashCode()方法的實(shí)現(xiàn)中使用相同的字段。 如果有任何變化影響所討論的字段,它將保證兩種方法的行為一致。

3.方法toString

toString()可以說(shuō)是其他方法中最有趣的方法,并且被更頻繁地覆蓋。 它的目的是提供對(duì)象(類實(shí)例)的字符串表示形式。 正確編寫(xiě)的toString()方法可以大大簡(jiǎn)化實(shí)際系統(tǒng)中問(wèn)題的調(diào)試和故障排除。

默認(rèn)的toString()實(shí)現(xiàn)在大多數(shù)情況下不是很有用,只是返回完整的類名和對(duì)象哈希碼,以@ ,fe分隔:

com.javacodegeeks.advanced.objects.Person@6104e2ee

讓我們嘗試改善實(shí)現(xiàn),并為我們的Person類示例重寫(xiě)toString()方法。 這是使toString()更有用的一種方法。

// Please add the @Override annotation, it will ensure that your // intention is to change the default implementation. @Override public String toString() {return String.format( "%s[email=%s, first name=%s, last name=%s]", getClass().getSimpleName(), email, firstName, lastName ); }

現(xiàn)在, toString()方法提供了Person類實(shí)例的字符串版本,包括其所有字段。 例如,在執(zhí)行以下代碼片段時(shí):

final Person person = new Person( "John", "Smith", "john.smith@domain.com" ); System.out.println( person.toString() );

以下輸出將在控制臺(tái)中打印出:

Person[email=john.smith@domain.com, first name=John, last name=Smith]

不幸的是,標(biāo)準(zhǔn)Java庫(kù)對(duì)簡(jiǎn)化toString()方法實(shí)現(xiàn)的支持有限,特別是,最有用的方法是Objects.toString() , Arrays.toString() / Arrays.deepToString() 。 讓我們看一下Office類及其可能的toString()實(shí)現(xiàn)。

package com.javacodegeeks.advanced.objects;import java.util.Arrays;public class Office {private Person[] persons;public Office( Person ... persons ) {this.persons = Arrays.copyOf( persons, persons.length );}@Overridepublic String toString() {return String.format( "%s{persons=%s}", getClass().getSimpleName(), Arrays.toString( persons ) );}public Person[] getPersons() {return persons;} }

以下輸出將在控制臺(tái)中打印出來(lái)(如我們所見(jiàn), Person類實(shí)例也已正確轉(zhuǎn)換為字符串):

Office{persons=[Person[email=john.smith@domain.com, first name=John, last name=Smith]]}

Java社區(qū)已經(jīng)開(kāi)發(fā)了幾個(gè)非常全面的庫(kù),這些庫(kù)在很大程度上toString()實(shí)現(xiàn)的工作。 其中包括Google Guava's Objects.toStringHelper和Apache Commons Lang ToStringBuilder 。

4.方法克隆

如果Java中有一種聲譽(yù)不佳的方法,則肯定是clone() 。 它的目的非常明確–返回正在調(diào)用的類實(shí)例的確切副本,但是有很多原因使它不像聽(tīng)起來(lái)那樣簡(jiǎn)單。

首先,如果您決定實(shí)現(xiàn)自己的clone()方法,則可以遵循Java文檔中規(guī)定的許多約定。 其次,該方法在Object類中聲明為protected ,因此為了使其可見(jiàn),應(yīng)使用重寫(xiě)類本身的返回類型將其重寫(xiě)為public 。 第三,覆蓋的類應(yīng)實(shí)現(xiàn)Cloneable接口(這只是一個(gè)未定義方法的標(biāo)記或mixin接口),否則將引發(fā)CloneNotSupportedException異常。 最后,實(shí)現(xiàn)應(yīng)首先調(diào)用super.clone() ,然后在需要時(shí)執(zhí)行其他操作。 讓我們看看如何為示例Person類實(shí)現(xiàn)它。

public class Person implements Cloneable {// Please add the @Override annotation, it will ensure that your// intention is to change the default implementation.@Overridepublic Person clone() throws CloneNotSupportedException {return ( Person )super.clone();} }

該實(shí)現(xiàn)看起來(lái)非常簡(jiǎn)單明了,那么這里可能出什么毛病? 實(shí)際上,有兩件事。 在執(zhí)行類實(shí)例的克隆時(shí),不會(huì)調(diào)用任何類構(gòu)造函數(shù)。 這種行為的結(jié)果是可能會(huì)出現(xiàn)意外的數(shù)據(jù)共享。 讓我們考慮上一節(jié)介紹的Office類的以下示例:

package com.javacodegeeks.advanced.objects;import java.util.Arrays;public class Office implements Cloneable {private Person[] persons;public Office( Person ... persons ) {this.persons = Arrays.copyOf( persons, persons.length );}@Overridepublic Office clone() throws CloneNotSupportedException {return ( Office )super.clone();}public Person[] getPersons() {return persons;} }

在此實(shí)現(xiàn)中, Office類實(shí)例的所有克隆都將共享同一個(gè)人數(shù)組,這不太可能實(shí)現(xiàn)所需的行為。 為了使clone()實(shí)現(xiàn)能夠做正確的事情,應(yīng)該做一些工作。

@Override public Office clone() throws CloneNotSupportedException {final Office clone = ( Office )super.clone();clone.persons = persons.clone();return clone; }

現(xiàn)在看起來(lái)更好,但是即使此實(shí)現(xiàn)也非常脆弱,因?yàn)閷⑷藛T字段定為final將導(dǎo)致相同的數(shù)據(jù)共享問(wèn)題(因?yàn)椴荒苤匦路峙鋐inal )。

總的來(lái)說(shuō),如果您想精確復(fù)制類,最好避免使用clone() / Cloneable并使用更簡(jiǎn)單的替代方法(例如,復(fù)制構(gòu)造函數(shù),具有C ++背景的開(kāi)發(fā)人員熟悉的概念或工廠)方法,這是我們?cè)诒窘坛痰?strong>第1部分“ 如何創(chuàng)建和銷毀對(duì)象”中討論的一種有用的構(gòu)造模式。

5.方法等于和==運(yùn)算符

Java ==運(yùn)算符和equals()方法之間存在有趣的關(guān)系,這會(huì)引起很多問(wèn)題和混亂。 在大多數(shù)情況下(比較原始類型除外), ==運(yùn)算符執(zhí)行引用相等:如果兩個(gè)引用都指向同一個(gè)對(duì)象,則返回true,否則返回false 。 讓我們看一個(gè)說(shuō)明差異的簡(jiǎn)單示例:

final String str1 = new String( "bbb" ); System.out.println( "Using == operator: " + ( str1 == "bbb" ) ); System.out.println( "Using equals() method: " + str1.equals( "bbb" ) );

從人類的角度來(lái)看,str1 ==“ bbb”和str1.equals(“ bbb”)之間沒(méi)有區(qū)別:在兩種情況下,結(jié)果都應(yīng)該相同,因?yàn)閟tr1只是對(duì)“ bbb”字符串的引用。 但是在Java中并非如此:

Using == operator: false Using equals() method: true

即使兩個(gè)字符串看起來(lái)完全相同,在此特定示例中,它們也作為兩個(gè)不同的字符串實(shí)例存在。 根據(jù)經(jīng)驗(yàn),如果您處理對(duì)象引用,請(qǐng)始終使用equals()或Objects.equals() (請(qǐng)參閱下一部分有用的幫助程序類以獲取更多詳細(xì)信息)進(jìn)行相等性比較,除非您確實(shí)有比較的意圖如果對(duì)象引用指向同一實(shí)例。

6.有用的助手類

自Java 7發(fā)行以來(lái),標(biāo)準(zhǔn)Java庫(kù)附帶了幾個(gè)非常有用的幫助程序類。 其中之一是Objects類。 特別地,以下三種方法可以大大簡(jiǎn)化您自己的equals()和hashCode()方法的實(shí)現(xiàn)。

方法 描述
static boolean equals(Object a, Object b) 如果參數(shù)彼此相等,則返回true,否則返回false
static int hash(Object... values) 為一系列輸入值生成哈希碼。
static int hashCode(Object o) 返回非空參數(shù)的哈希碼,對(duì)于空參數(shù)返回0。

表2

如果我們使用這些輔助方法為Person的類示例重寫(xiě)equals()和hashCode()方法,則代碼量將大大減少,并且代碼的可讀性也將大大提高。

@Override public boolean equals( Object obj ) {if ( obj == null ) {return false;}if ( this == obj ) {return true;}if ( getClass() != obj.getClass() ) {return false;}final PersonObjects other = (PersonObjects) obj;if( !Objects.equals( email, other.email ) ) {return false;} else if( !Objects.equals( firstName, other.firstName ) ) {return false; } else if( !Objects.equals( lastName, other.lastName ) ) {return false; }return true; }@Override public int hashCode() {return Objects.hash( email, firstName, lastName ); }

7.下載源代碼

  • 您可以在此處下載源代碼: advanced-java-part-2

8.接下來(lái)

在本節(jié)中,我們介紹了Object類,它是Java中面向?qū)ο缶幊痰幕A(chǔ)。 我們已經(jīng)看到了每個(gè)類如何重寫(xiě)從Object類繼承的方法并強(qiáng)加其自己的相等性規(guī)則。 在下一節(jié)中,我們將轉(zhuǎn)換編碼方式,并討論如何正確設(shè)計(jì)類和接口。

翻譯自: https://www.javacodegeeks.com/2015/09/using-methods-common-to-all-objects.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的使用所有对象共有的方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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