詳解Java編程中包package的內(nèi)容與包對(duì)象的規(guī)范
包的內(nèi)容
包的內(nèi)容應(yīng)該仔細(xì)設(shè)計(jì),使其只包含在功能上相關(guān)的類和接口。包中的類可以自由地訪問(wèn)該包中其他類的非私有成員,有些類甚至可能有足夠的權(quán)限去訪問(wèn)其他類的內(nèi)部細(xì)節(jié),為了避免這樣的類對(duì)類成員進(jìn)行誤操作,我們需要對(duì)類成員進(jìn)行保護(hù)。任何沒有被聲明為private的成員都可以被同一個(gè)包中的其他所有類型訪問(wèn),所以任何不相關(guān)的類之間的藕合程度都可能會(huì)比我們所期望的程度高。
包還為尋找有用的接口和類的程序員提供了邏輯分組的功能。由不相關(guān)的類組成的包使程序員很難分辨出哪些接口和類是有用的,而類的邏輯分組可以幫助程序員重用代碼,因?yàn)槌绦騿T通過(guò)邏輯分組能夠更容易地找到他們所需要的東西。如果包中只包含相關(guān)的、緊藕合的類型集,則意味著我們可以給類型取一些更直觀的名字,從而避免名字沖突。
包可以嵌套。例如,java.lang就是一個(gè)嵌套包,其中,包Lang嵌套在更大的包java中,而包j ava卻還包含一些其他的包。嵌套使得相關(guān)的包構(gòu)成了具有層次結(jié)構(gòu)的命名系統(tǒng)。
例如,為了創(chuàng)建一組包,用于諸如神經(jīng)網(wǎng)絡(luò)和遺傳算法這樣的自適應(yīng)系統(tǒng),我們可以用以圓點(diǎn)分隔的名字來(lái)命名包,從而創(chuàng)建嵌套包:
package adaptive. neural Net;
含有上面這條聲明語(yǔ)句的源文件位于adaptive.neuralNet包中,而adaptive.neuralNet包本身又是adaptive包的子包。adaptive包中可能包含一些與通用的自適應(yīng)算法相關(guān)的類,例如泛化問(wèn)題陳述類或基準(zhǔn)測(cè)試類。在層次結(jié)構(gòu)中處于更深位置的包(例如adaptive. neu-ralNet或adaptive.genetic)包含與特定類型的自適應(yīng)算法相關(guān)的類。
包的嵌套僅僅是組織相關(guān)包的一種工具,它并不能提供包之間的任何特殊的訪問(wèn)權(quán)限。
adaptive.genetic包中的類代碼無(wú)法訪問(wèn)adaptive或adaptive.neuralNet包中具有包訪問(wèn)權(quán)限的成員,包作用域只適用于特定的包。包的嵌套可以對(duì)相關(guān)的包進(jìn)行分組,并幫助程序員更方便地在邏輯層次中找到想要的類,但是除此之外,它并未帶來(lái)其他的任何益處。
包的注解
包也可以有注解。但是問(wèn)題在于,由于包是一種組織結(jié)構(gòu),沒有源代碼實(shí)體,它們并沒有實(shí)際的定義,所以不能像對(duì)類或方法那樣對(duì)它們進(jìn)行注解,因此包的注解只能通過(guò)在源文件中對(duì)包的聲明語(yǔ)句進(jìn)行注解來(lái)實(shí)現(xiàn)。然而,在每個(gè)包中只能有一個(gè)包聲明可以擁有作用于它的注解。
那么究竟如何對(duì)包進(jìn)行注解呢?事實(shí)上,Java語(yǔ)言并沒有強(qiáng)制程序員必須使用某種方式來(lái)處理“單一注解的包語(yǔ)句”規(guī)則。所建議的方式是在包目錄中創(chuàng)建一個(gè)名為package一i nfo.java的文件,在這個(gè)文件中只存儲(chǔ)包語(yǔ)句和該包的注解,而不放置任何其他內(nèi)容。例如,用于attr包的package一info.java文件看起來(lái)就是這樣的:
@PackageSpec(name二”Attr Project",version="1.0" @DevelopmentSite("attr.project.org") @DevelopmentModel("open一source") package attr;
其中Packagespec,Developmentsite和Devel opmentmodel用來(lái)修飾注解類型,當(dāng)然,它們具有運(yùn)行時(shí)的保存策略。package一info.java文件應(yīng)該和包中的其他源文件一起編譯。
我們推薦將所有與包相關(guān)的信息都放置在package一info. java文件中。如果你這樣做了,那么你就可以在文件的開頭放置文檔注釋,從而使這些文檔被注釋成包文檔。
包對(duì)象和規(guī)范
包通常會(huì)實(shí)現(xiàn)某種規(guī)范,并且通常是來(lái)自于某個(gè)組織的。Package對(duì)象與其他的反射類型不同,不能用來(lái)創(chuàng)建或操作包,而只能充當(dāng)提供信息的知識(shí)庫(kù),用來(lái)提供有關(guān)包所實(shí)現(xiàn)的規(guī)范的信息(規(guī)范的標(biāo)題、供應(yīng)商和版本號(hào))和有關(guān)包的實(shí)現(xiàn)本身的信息(包的標(biāo)題、供應(yīng)商和版本號(hào))。雖然包通常來(lái)自于單個(gè)的組織,但它所實(shí)現(xiàn)的規(guī)范(如統(tǒng)計(jì)分析庫(kù))卻可能是其他組織已定義過(guò)的。使用包的程序可能需要知道該包所實(shí)現(xiàn)的規(guī)范的版本,從而可以使用只在某個(gè)版本中定義的功能。類似地,這些程序還可能需要知道提供給它的是哪個(gè)實(shí)現(xiàn)版本,這主要是為了處理在不同版本中可能存在的缺陷。Package類的一些主要方法允許訪問(wèn)到這些信息:
- ·public Stri ng getName ():返回該包的名字。
- .public string getspecificationTitle p:返回該包所實(shí)現(xiàn)的規(guī)范的標(biāo)題,如果標(biāo)題未知,則返回null,
- .public string getspecificationversion():返回一個(gè)描述該包所實(shí)現(xiàn)的規(guī)范的版本信息的字符串,如果版本信息未知,則返回null,
- .public string getspecificationvendor Q:返回供應(yīng)商的名字,這個(gè)供應(yīng)商擁有并維護(hù)該包所實(shí)現(xiàn)的規(guī)范,如果供應(yīng)商未知,則返回null,
- .public string getImplerentationTitle():返回該包所提供的實(shí)現(xiàn)的標(biāo)題,如果標(biāo)題未知,則返回null, ·public string getImplementationversion():返回一個(gè)描述該包所提供的實(shí)現(xiàn)的版本信息的字符串,如果版本信息未知,則返回null,
- ·public string getImplementationvendor():返回提供該實(shí)現(xiàn)的組織(供應(yīng)商)的名字,如果該組織未知,則返回null,
例如,在我們的系統(tǒng)中提取java.lang包的這些信息,將會(huì)得到如下結(jié)果:'
Specification Title: Java Platform API Specification Specification Version: 1.4 Specification Vendor:Sun Microsystems,Inc. Implementation Title:Java Runtime Environment Implementation Version:1.5.0_02 Implementation Vendor: Sun Microsystems,Inc.
規(guī)范版本號(hào)由句點(diǎn)分隔符分開的非負(fù)數(shù)字組成,如‘'2.0'‘或”11.0.12"。這種模式使得我們可以調(diào)用iscompatiblewith方法對(duì)遵循該模式的版本號(hào)與包的版本號(hào)進(jìn)行比較。如果包的版本號(hào)大于等于傳人的版本號(hào),那么該方法就返回true。這種比較每次只比較一個(gè)由句點(diǎn)分隔的數(shù)字,如果這些數(shù)字中任何一個(gè)小于傳遞進(jìn)來(lái)的版本號(hào)中對(duì)應(yīng)位置的值,那么這兩個(gè)版本就不兼容。如果其中一個(gè)版本號(hào)比另一個(gè)長(zhǎng),那么在短的版本號(hào)中缺少的部分將被認(rèn)為是零。例如,如果包的規(guī)范版本號(hào)是”1.4",并且我們用iscompatiblewith方法將其與”1.2","1.3.1'.或”.1.81.進(jìn)行比較時(shí),那么將返回true;但是如果與''1.4.2'.或”.5"進(jìn)行比較,那么將返回false。之所以得出這樣的結(jié)論,是因?yàn)檫@種比較機(jī)制假設(shè)規(guī)范版本是向后兼容的。
實(shí)現(xiàn)的版本號(hào)沒有規(guī)定的格式,因?yàn)樘峁?shí)現(xiàn)的不同組織會(huì)對(duì)實(shí)現(xiàn)版本做不同的定義。在實(shí)現(xiàn)版本之間唯一能做的比較是測(cè)試版本是否相同,其中沒有向下兼容的假設(shè)。
包可以被密封起來(lái),這意味著不能再向這個(gè)包中添加類了。未密封的包可以包含來(lái)自類搜索路徑中多個(gè)不同位置的類,而被密封的包的內(nèi)容必須來(lái)自相同的位置—要么是某個(gè)特定的歸檔文件,要么是由某個(gè)URL指定的位置。有兩種方法可以確定一個(gè)包是否被密封了:
.public boolean issealed p:如果該包被密封了,則返回trueo
.public boolean issealed(URL url):如果該包對(duì)于給定的URL是密封的,則返回true,也就是說(shuō),該包中的類可以從這個(gè)給定的URL處加載。如果包中的類不能從給定的URL加載,或者包沒有被密封,則返回false,包的規(guī)范和實(shí)現(xiàn)信息通常是作為與包存儲(chǔ)在一起的清單文件的一部分而提供的—例如作為Java歸檔文件(jar)中的清單文件的一部分,就像25.9.2節(jié)“歸檔文件java.util.jar”中描述的那樣。當(dāng)加載包中類時(shí),這些信息就會(huì)被讀人。類加載器(ClassLoader)可以為它要加載的類動(dòng)態(tài)地定義一個(gè)Package對(duì)象:
我們可以調(diào)用給定類的Class對(duì)象的getPackage方法來(lái)獲得這個(gè)類的Package對(duì)象。我們也可以用給定的包名調(diào)用靜態(tài)方Package.getPackage來(lái)獲得Package對(duì)象,或者調(diào)用靜態(tài)方Package.getPackages,它將返回由類加載器當(dāng)前已知的所有包組成Package數(shù)組。這兩個(gè)方法都與調(diào)用它們的代碼的類加載器有關(guān),因?yàn)檫@些代碼將調(diào)用其類加載器的get-Package或getPackages方法。這些類加載器的方法將搜索特定的類加載器及其所有父類加載器,如果對(duì)當(dāng)前類加載器沒有做任何設(shè)置,那么此時(shí)就會(huì)使用系統(tǒng)類加載器。請(qǐng)注意,如果包未知,那么類加載器方法將返回null,因?yàn)榇藭r(shí)還沒有加載包中的任何類型。
相關(guān)文章
springboot2.x 接入阿里云市場(chǎng)短信發(fā)送的實(shí)現(xiàn)
本文主要介紹了springboot2.x 接入阿里云市場(chǎng)短信發(fā)送的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11MyBatisPlus分頁(yè)時(shí)排序的實(shí)現(xiàn)
本文主要介紹了MyBatisPlus分頁(yè)時(shí)排序的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03基于JPA實(shí)體類監(jiān)聽器@EntityListeners注解的使用實(shí)例
這篇文章主要介紹了JPA實(shí)體類監(jiān)聽器@EntityListeners注解的使用實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Springboot基于assembly的服務(wù)化打包方案及spring boot部署方式
這篇文章主要介紹了Springboot基于assembly的服務(wù)化打包方案及springboot項(xiàng)目的幾種常見的部署方式,本文主要針對(duì)第二種部署方式提供一種更加友好的打包方案,需要的朋友可以參考下2017-12-12java模擬post請(qǐng)求發(fā)送json的例子
本篇文章主要介紹了java模擬post請(qǐng)求發(fā)送json的例子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08java swing 實(shí)現(xiàn)加載自定義的字體
這篇文章主要介紹了java swing 實(shí)現(xiàn)加載自定義的字體,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11SpringBoot項(xiàng)目中分頁(yè)插件PageHelper無(wú)效的問(wèn)題及解決方法
這篇文章主要介紹了解決SpringBoot項(xiàng)目中分頁(yè)插件PageHelper無(wú)效的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06解決springboot項(xiàng)目啟動(dòng)失敗Could not initialize class&
這篇文章主要介紹了解決springboot項(xiàng)目啟動(dòng)失敗Could not initialize class com.fasterxml.jackson.databind.ObjectMapper問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06如何使用Java將word解析出來(lái)(包含格式和圖片)
今天遇到一個(gè)讀取word模板內(nèi)容的需求,下面這篇文章主要給大家介紹了關(guān)于如何使用Java將word解析出來(lái),包含格式和圖片,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12