国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Java中怎么通過(guò)創(chuàng )建對象來(lái)提升程序性能

發(fā)布時(shí)間:2021-07-03 23:03 來(lái)源:億速云 閱讀:0 作者:Leah 欄目: 開(kāi)發(fā)技術(shù)

本篇文章給大家分享的是有關(guān)Java中怎么通過(guò)創(chuàng )建對象來(lái)提升程序性能,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習,希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著(zhù)小編一起來(lái)看看吧。

在 Java 中有多種方式可以創(chuàng )建對象,總結起來(lái)主要有下面的 4 種方式:

正常創(chuàng )建:通過(guò) new 操作符

反射創(chuàng )建:調用 Class 或 java.lang.reflect.Constructor 的 newInstance()方法

克隆創(chuàng )建:調用現有對象的 clone()方法

發(fā)序列化:調用 java.io.ObjectInputStream 的 getObject()方法反序列化

Java 對象的創(chuàng )建方式是其語(yǔ)法明確規定,用戶(hù)不可能從外部改變的。本文仍然要使用上面的方式來(lái)創(chuàng )建對象,所以本文只能說(shuō)是構建對象,而非創(chuàng )建對象也。

假設有這樣一個(gè)場(chǎng)景,現在要構建一個(gè)大型的對象,這個(gè)對象包含許多個(gè)參數的對象,有些參數有些是必填的,有些則是選填的。那么如何構建優(yōu)雅、安全地構建這個(gè)對象呢?

01 單一構造函數

通常,我們第一反應能想到的就是單一構造函數方式。直接 new 的方式構建,通過(guò)構造函數來(lái)傳遞參數,見(jiàn)下面的代碼:

/*** * 單一構造函數 */ public class Person { // 姓名(必填) private String name; // 年齡(必填) private int age; // 身高(選填) private int height; // 畢業(yè)學(xué)校(選填) private String school; // 愛(ài)好(選填) private String hobby; public Person(String name, int age, int height, String school, String hobby) { this.name = name; this.age = age; this.height = height; this.school = school; this.hobby = hobby; } }

上面的構建方式有下面的缺點(diǎn):

有些參數是可以選填的(如 height, school),在構建 Person 的時(shí)候必須要傳入可能并不需要的參數。

現在上面才 5 個(gè)參數,構造函數就已經(jīng)非常長(cháng)了。如果是 20 個(gè)參數,構造函數都可以直接上天了!

構建的這樣的對象非常容易出錯。

客戶(hù)端必須要對照 Javadoc 或者參數名來(lái)講實(shí)參傳入對應的位置。如果參數都是 String 類(lèi)型的,一旦傳錯參數,編譯是不會(huì )報錯的,但是運行結果卻是錯誤的。

02 多構造函數

對于第 1 個(gè)問(wèn)題,我們可以通過(guò)構造函數重載來(lái)解決。見(jiàn)下面的代碼:

/*** * 多構造函數 */ public class Person { // 姓名(必填) private String name; // 年齡(必填) private int age; // 身高(選填) private int height; // 畢業(yè)學(xué)校(選填) private String school; // 愛(ài)好(選填) private String hobby; public Person(String name, int age) { this.name = name; this.age = age; } public Person(String name, int age, int height) { this.name = name; this.age = age; this.height = height; } public Person(String name, int age, int height, String school) { this.name = name; this.age = age; this.height = height; this.school = school; } public Person(String name, int age, String hobby, String school) { this.name = name; this.age = age; this.hobby = hobby; this.school = school; } }

上面的方式確實(shí)能在一定程度上降低構造函數的長(cháng)度,但是卻有下面的缺陷:

導致類(lèi)過(guò)長(cháng)。這種方式會(huì )使得 Person 類(lèi)的構造函數成階乘級增長(cháng)。按理來(lái)說(shuō),應該要寫(xiě)的構造函數數是可選成員變量的組合數(實(shí)際并沒(méi)有這么多,原因見(jiàn)第 2 點(diǎn))。如果讓我調用這樣的類(lèi),絕對會(huì )在心里默念 xx!!

有些參數組合無(wú)法重構。因為 Java 中重載是有限制的,相同方法簽名的方法不能構成重載,編譯時(shí)無(wú)法通過(guò)。譬如包含(name, age, school)和(name, age, hobby)的構造函數是不能重載的,因為 shcool 和 hobby 同為 String 類(lèi)型。Java 只認變量的類(lèi)型,管你變量是什么含義呢。

03 JavaBean方式

上面的方法不行,莫急!還有法寶——JavaBean。一個(gè)對象的構建通過(guò)多個(gè)方法來(lái)完成。直接見(jiàn)下面的代碼:

public class Person { // 姓名(必填) private String name; // 年齡(必填) private int age; // 身高(選填) private int height; // 畢業(yè)學(xué)校(選填) private String school; // 愛(ài)好(選填) private String hobby; public Person(String name, int age) { this.name = name; this.age = age; } public void setHeight(int height) { this.height = height; } public void setSchool(String school) { this.school = school; } public void setHobby(String hobby) { this.hobby = hobby; } } 客戶(hù)端使用這個(gè)對象的代碼如下: public class Client { public static void main(String[] args) { Person person = new Person("james", 12); person.setHeight(170); person.setHobby("reading"); person.setSchool("xxx university"); } }

這樣看起來(lái)完美的解決了 Person 對象構建的問(wèn)題,使用起來(lái)非常優(yōu)雅便捷。確實(shí),在單一線(xiàn)程的環(huán)境中這確實(shí)是一個(gè)非常好的構建對象的方法,但是如果是在多線(xiàn)程環(huán)境中仍有其致命缺陷。在多線(xiàn)程環(huán)境中,這個(gè)對象不能安全地被構建,因為它不是不可變對象。一旦Person 對象被構建,我們隨時(shí)可通過(guò) setXXX()方法改變對象的內部狀態(tài)。假設有一個(gè)線(xiàn)程正在執行與 Person 對象相關(guān)的業(yè)務(wù)方法,另外一個(gè)線(xiàn)程改變了其內部狀態(tài),這樣得到莫名其妙的結果。由于線(xiàn)程運行的無(wú)規律性,使得這問(wèn)題有可能不能重現,這個(gè)時(shí)候真的就只能哭了。

04 Builder方式

為了完美地解決這個(gè)問(wèn)題,下面引出本文中的主角(等等等等?。?。我們使用構建器(Builder)來(lái)優(yōu)雅、安全地構建 Person 對象。廢話(huà)不說(shuō),直接代碼:

/** * 待構建的對象。該對象的特點(diǎn): * <ol> * <li>需要用戶(hù)手動(dòng)的傳入多個(gè)參數,并且有多個(gè)參數是可選的、順序隨意</li> * <li>該對象是不可變的(所謂不可變,就是指對象一旦創(chuàng  )建完成,其內部狀態(tài)不可變, 更通俗的說(shuō)是其成員變量不可改變)。* 不可變對象本質(zhì)上是線(xiàn)程安全的。</li> * <li>對象所屬的類(lèi)不是為了繼承而設計的。</li> * </ol> * 滿(mǎn)足上面特點(diǎn)的對象的構建可是使用下面的 Build 方式構建。這樣構建對象有下面的好 處: * <ol> * <li>不需要寫(xiě)多個(gè)構造函數,使得對象的創(chuàng  )建更加便捷</li> * <li>創(chuàng  )建對象的過(guò)程是線(xiàn)程安全的</li> * </ol> * @author xiaoyu * @date 2020-10-25 */ public class Person { // 姓名(必填),final 修飾 name 一旦被初始化就不能再改變,保證了對象的不可變 性。 private final String name; // 年齡(必填) private final int age; // 身高(選填) private final int height; // 畢業(yè)學(xué)校(選填) private final String school; // 愛(ài)好(選填) private final String hobby; /** * 這個(gè)私有構造函數的作用: * <ol> * <li>成員變量的初始化。final 類(lèi)型的變量必須進(jìn)行初始化,否則無(wú)法編譯成功</li> * <li>私有構造函數能夠保證該對象無(wú)法從外部創(chuàng  )建,并且 Person 類(lèi)無(wú)法被繼承</li> * </ol> */ private Person(String name, int age, int height, String school, String hobby) { this.name = name; this.age = age; this.height = height; this.school = school; this.hobby = hobby; } /** * 要執行的動(dòng)作 */ public void doSomething() { // TODO do what you want!! } /** * 構建器。為什么 Builder 是內部靜態(tài)類(lèi)? * <ol> * <li>必須是 Person 的內部類(lèi)。否則,由于 Person 的構造函數私有,不能通過(guò) new 的 方式創(chuàng  )建 Person 對象</li> * <li>必須是靜態(tài)類(lèi)。由于 Person 對象無(wú)法從外部創(chuàng  )建,如果不是靜態(tài)類(lèi),則外部無(wú) 法引用 Builder 對象。</li> * </ol> * <b>注意</b>:Builder 內部成員變量要與 Person 的成員變量保持一致。 * @author xiaoyu * */ public static class Builder { // 姓名(必填)。注意:這里不能是 final 的 private String name; // 年齡(必填) private int age; // 身高(選填) private int height; // 畢業(yè)學(xué)校(選填) private String school; // 愛(ài)好(選填) private String hobby; public Builder(String name, int age) { this.name = name; this.age = age; } public Builder setHeight(int height) { this.height = height; return this; } public Builder setSchool(String school) { this.school = school; return this; } public Builder setHobby(String hobby) { this.hobby = hobby; return this; } /** * 構建對象 * @return 返回待構建的對象本身 */ public Person build() { return new Person(name, age, height, school, hobby); } } }

客戶(hù)端構建對象的方式見(jiàn)下面的代碼:

/** * 使用 Person 對象的客戶(hù)端 * @author xiaoyu * @date 2020-10-25 */ public class Client { public static void main(String[] args) { /* * 通過(guò)鏈式調用的方式創(chuàng  )建 Person 對象,非常優(yōu)雅! */ Person person = new Person.Builder("james", 12) .setHeight(170) .setHobby("reading") .build(); person.doSomething(); } }

如果不想看代碼,可看下面對于上面代碼的總結:

通過(guò) private Person(..)使得 Person 類(lèi)不可被繼承

通過(guò)將 Person 類(lèi)的成員變量設置為 final 類(lèi)型,使得其不可變

通過(guò) Person 內部的 static Builder 類(lèi)來(lái)構建 Person 對象

通過(guò)將 Builder 類(lèi)內部的 setXXX()方法返回 Builder 類(lèi)型本身,實(shí)現鏈式調用構建 Person 對 象

總結

至此,我們就相對完美地解決這一類(lèi)型的對象創(chuàng )建問(wèn)題!下面來(lái)總結一下本文的重點(diǎn)。待創(chuàng )建的對象特點(diǎn):

需要用戶(hù)手動(dòng)的傳入多個(gè)參數,并且有多個(gè)參數是可選的、順序任意

對象不可變

對象所屬的類(lèi)不是為了繼承而設計的。即類(lèi)不能被繼承

依次使用的對象構建方法:

單一構造函數

多構造函數

JavaBean 方式

Builder 方式

最終,通過(guò)比較得出 Builder 方法最為合適的解決。

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

亚洲欧美日韩中文无线码| 亚洲国产精品久久久久久无码| 无码免费视频AAAAAA片草莓| 久久国内精品自在自线400部| 在线高清理伦片| 国模和精品嫩模私拍视频|