聊一聊 Java 面向?qū)ο?/h1>
前言
在之前的文章中,講到了面向的 3 大特性(封裝、繼承、多態(tài))和面向?qū)ο笤O(shè)計(jì)的 5 大原則(SRP、OCP、LSP、DIP、ISP)。此外,我們還講了如何創(chuàng)建一個(gè)類,并且在創(chuàng)建類后如何構(gòu)造一個(gè)對(duì)象。然后還介紹了類中的屬性和方法,并對(duì)構(gòu)造方法和引用也做了簡(jiǎn)單的講解。
有了上面的基礎(chǔ)之后,今天我們來(lái)繼續(xù)學(xué)習(xí)面向?qū)ο蟮南嚓P(guān)知識(shí),主要內(nèi)容預(yù)告如下:
- 包
- 注釋
- jar 文件的創(chuàng)建
包
假設(shè)現(xiàn)在有這么一種情況,諸葛亮、周瑜、曹操共同開(kāi)發(fā)一款程序。其中,周瑜和曹操均在自己代碼模塊中寫了一個(gè) PublicUtil 類,現(xiàn)在諸葛亮要調(diào)用周瑜和曹操模塊中代碼,需要同時(shí)用到他們中的 PublicUtil 類,這時(shí)候就犯難了,諸葛亮在他的代碼中使用 PublicUtil 類時(shí),該怎么區(qū)分是調(diào)用周瑜的,還是調(diào)用的曹操的呢?
針對(duì)這個(gè)問(wèn)題,開(kāi)發(fā) Java 的前輩們當(dāng)然也想到了。于是,他們?cè)?Java 中定義了一種名字空間,也就是我們今天要講的包:package。通過(guò)使用包機(jī)制,就十分容易區(qū)別類名的命名空間了。
假設(shè)曹操的 PublicUtil 類代碼如下:
// 申明包名package caocao;public class PublicUtil{ ……}
周瑜的 PublicUtil 類代碼如下:
// 申明包名package zhouyu;public class PublicUtil{ ……}
此時(shí),如果諸葛亮要同時(shí)使用他們倆代碼中的 PublicUtil 類,此時(shí)就可以通過(guò)引入他們倆的包,然后通過(guò)使用 包名.類名 的引用方式來(lái)進(jìn)行區(qū)分即可。
package zhugeliang;import caocao;import zhouyu;public class Util{ // 使用周瑜代碼 zhouyu.PublicUtil.xxx(); …… // 使用曹操代碼 caocao.PublicUtil.xxx(); ……}
以上代碼中的 import 你可能也在其他代碼中見(jiàn)到過(guò),但你不知道啥作用。其實(shí)它就是為了包的使用而生,如果我要使用另一個(gè)人的包,那該怎么做呢?其實(shí)很簡(jiǎn)單,只需要在程序中使用關(guān)鍵字 import 即可完成包的導(dǎo)入。
通過(guò)使用包,可以達(dá)到以下的作用:
- 將功能類似或或相關(guān)的類以及接口組織放在同一個(gè)包中,方便類的查找與使用。
- 包也像文件夾一樣,采用了樹(shù)形目錄的存儲(chǔ)方式。同一個(gè)包中的類名不同,不同包中的類名可以相同。當(dāng)同時(shí)調(diào)用兩個(gè)不同包中的同一類名的類時(shí),通過(guò)加上完整的包名就可以加以區(qū)分,從而避免類名沖突。
- 同時(shí)包也限定了訪問(wèn)權(quán)限,只有擁有包訪問(wèn)權(quán)限的類才能間接去訪問(wèn)包中的類。
注釋
所謂注釋,就是寫在程序里邊對(duì)代碼進(jìn)行結(jié)束說(shuō)明的文字,既方便自己也方便他人查看,更快理解程序含義。而且注釋是不影響程序的執(zhí)行的,在我們對(duì) Java 源代碼進(jìn)行編譯后,字節(jié)碼文件中不含源代碼中的注釋內(nèi)容。
在 Java 中,通常支持三種注釋方式,它們分別是:
- //:?jiǎn)涡凶⑨?/li>
- /* */:多行注釋
- /** */:文檔注釋
單行注釋
單行注釋是以雙斜杠 // 來(lái)標(biāo)識(shí),表示只注釋當(dāng)前行內(nèi)容,一般用在需要注釋的內(nèi)容較少的地方,以下就是一個(gè)單行注釋的實(shí)例。
// 第一個(gè) Java 程序public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!"); }}
多行注釋
通常我們把要注釋的內(nèi)容放在 /* 和 */ 之間,表示在兩者之間的內(nèi)容都是我們的注釋內(nèi)容,以下是一個(gè)多行注釋的實(shí)例。
/** 第一個(gè) Java 程序* 這是許多初學(xué)者都會(huì)寫的一個(gè)程序*/public class HelloWorld{ public static void main(String[] args){ System.out.println("Hello World!"); }}
文檔注釋
文檔注釋和多行注釋很像,它是將我們所需要注釋的內(nèi)容包含在 /** 和 */ 之間。而文檔注釋和其他兩種注釋最大的區(qū)別就在于:我們可以利用 javadoc 工具來(lái)提取文檔注釋,然后生成一個(gè) HTML 文檔,類似于 Java 官網(wǎng)所提供的 API 文檔,以下是一個(gè)文檔注釋的實(shí)例。
/*** 第一個(gè) Java 程序* 這是許多初學(xué)者都會(huì)寫的一個(gè)程序*/public class HelloWorld{ /** * 主函數(shù) * @param args 主函數(shù)參數(shù)列表 */ public static void main(String[] args){ System.out.println("Hello World!"); }}
然后我們通過(guò)終端,使用 javadoc 命令就可以為上述文件生成一個(gè) HTML 文檔。
javadoc HelloWorld.java
而文檔注釋相比于其他兩種注釋,也有更多值得注意的地方,下面就分別來(lái)看看需要留意的地方。
1、常用文檔注釋分類
- ?類注釋
顧名思義,所謂類注釋,就是針對(duì)整個(gè)類的說(shuō)明,它必須放在 import 之后,但又必須放在類定義之前。以下是一個(gè)類注釋的實(shí)例:
/*** Animal,動(dòng)物類*/public class Animal{ ...}
這里需要注意的是,在 /** 和 */ 之間的其他行注釋,* 是可有可無(wú)的,之所以加上,更大情況出于美觀的考慮,上面的實(shí)例寫成如下樣式也是合法的。
/** Animal,動(dòng)物類*/public class Animal{ ...}
- 方法注釋
同樣的,方法注釋也就是針對(duì)類中方法的注釋,它必須放在所描述的方法之前。而一般情況下,除開(kāi)說(shuō)明該方法的功能之外,我們經(jīng)常使用如下標(biāo)記來(lái)對(duì)方法進(jìn)行注釋。
標(biāo)記說(shuō)明@param variable description用于介紹當(dāng)前方法的參數(shù),可以占據(jù)多行@return description用于描述當(dāng)前方法的返回值,可以跨多行@throws class description用于表示該方法有可能拋出的異常。
以下就是一個(gè)方法注釋的實(shí)例:
/*** 求兩數(shù)之h* @param num1 加數(shù)1* @param num2 加數(shù)2@ return 兩數(shù)之和*/public int add(int num1, int num2){ return num1 + num2;}
- 字段注釋
字段注釋顧名思義,也就是對(duì)于類中字段的說(shuō)明,用于描述字段的含義,以下是一個(gè)字段注釋的例子。
public class Cunyu{ /** * 公眾號(hào) */ public String wePublic;}
當(dāng)然,如果你不喜歡把一個(gè)字段的注釋分成多行的話,也可以寫成以下格式。
public class Cunyu{ /**公眾號(hào)*/ public String wePublic;}
兩種方式都是可以的,也沒(méi)有優(yōu)劣之分,可以根據(jù)自己的風(fēng)格來(lái)選擇。但是在 IntelliJ IDEA 等 IDE 中,如果對(duì)代碼進(jìn)行格式化,IDEA 會(huì)將第二種方式格式化成第一種方式,這一點(diǎn)需要注意。
2、如何提取文檔注釋
假設(shè)有以下一段代碼,我們需要生成關(guān)于代碼的文檔說(shuō)明。那么就可以使用 JDK 中所提供的 javadoc 命令來(lái)提取代碼的文檔注釋。
/*** 第一個(gè) Java 程序* 這是初學(xué)者基本都會(huì)寫的一個(gè)程序* @author 村雨遙* @version 1.0*/public class HelloWorld { /** * 主函數(shù):程序入口 * @param args 主函數(shù)參數(shù)列表 */ public static void main(String[] args){ System.out.println("Hello World!"); }}
然后利用以下命令就可以生成我們的文檔注釋。
javadoc -d helloworld -author -version -encoding UTF-8 HelloWorld.java
以上命令的意思就是,對(duì)名為 HelloWorld.java 的提取其中的文檔注釋,并將輸出的文件放在 helloworld 文件夾下,并且在文檔中包含程序作者和版本,編碼方式為 UTF-8。
生成的文件列表詳情見(jiàn)下圖,打開(kāi)其中的 index.html 就可以查看提取的文檔注釋。
jar 文件的創(chuàng)建
其實(shí)關(guān)于這個(gè),我在之前的文章也寫過(guò)。不過(guò)我是利用 IntelliJ IDEA 來(lái)對(duì)進(jìn)行代碼的打包,如果感興趣,可以點(diǎn)擊下方傳送門去看看。
如何利用 IntelliJ IDEA 創(chuàng)建 Java 入門應(yīng)用[1]。
不過(guò)那是借助工具來(lái)生成的,今天我們來(lái)看看如何利用 JDK 所提供的命令行工具,來(lái)創(chuàng)建一個(gè)能打印出 Hello World! 的 jar 包。
同樣的,我們?nèi)匀皇切枰葴?zhǔn)備一個(gè)能輸出 Hello World! 的 Java 源代碼,命名為 HelloWorld.java。
public class HelloWorld { public static void main(String[] args){ System.out.println("Hello World!"); }}
接著,利用 javac 命令對(duì)該文件進(jìn)行編譯,然后會(huì)生成 HelloWorld.class 字節(jié)碼文件。
javac HelloWorld.java
然后,利用 jar 命令來(lái)對(duì)生成的字節(jié)碼文件進(jìn)行打包。
jar -cvf hello.jar HelloWorld.class
其中 c 表示創(chuàng)建一個(gè)新 jar 包,v 表示創(chuàng)建過(guò)程中打印創(chuàng)建過(guò)程中的信息,f 則表示對(duì)新生成的 jar 命名。
最后,利用以下命令來(lái)運(yùn)行 jar 包。
java -jar hello.jar
不過(guò)并不會(huì)順利出現(xiàn)我們想要的結(jié)果,此時(shí)會(huì)報(bào)錯(cuò) hello.jar 中沒(méi)有主清單屬性。這是因?yàn)槲覀冞€沒(méi)有在 MENIFEST.MF 文件中添加 Main-Class 屬性。
用壓縮軟件打開(kāi)剛創(chuàng)建的 hello.jar,里邊除了 HelloWorld.class 文件之外,還會(huì)多一個(gè) META-INF 文件夾,里邊還有一個(gè) MENIFEST.MF 文件,此時(shí)我們只需要用編輯器打開(kāi)該文件,然后在文件中加入以下代碼。(記得添加之后要保證整個(gè)文件最后保留一行空行)。
Main-Class: HelloWorld
添加完成之后,再次運(yùn)行 java -jar hello.jar ,就可以成功在控制臺(tái)打印 Hello World! 了。
參考資料
[1]如何利用 IntelliJ IDEA 創(chuàng)建 Java 入門應(yīng)用: https://cunyu1943.github.io/JavaPark/dev-tools/idea/java-quick-start-with-idea。