【Java】命令行下的Java包结构编译与执行
編寫代碼
com.hhh.test.PackageTest
package com.hhh.test;public class PackageTest {public static void main(String[] args) {System.out.println("Hello World");} }com.hhh.test2.PackageTest2
package com.hhh.test2;import com.hhh.test.PackageTest;public class PackageTest2 {public static void main(String[] args) {PackageTest obj = new PackageTest();System.out.println("Hello World");} }預(yù)處理
跳轉(zhuǎn)到指定區(qū)域
- PackageTest.java、PackageTest2.java文件放到D:\PackageTest路徑下。
- cmd輸入D: ,從C盤切到D盤。
- 輸入命令cd D:\PackageTest,跳轉(zhuǎn)到指定路徑下。
編譯第一個(gè)文件
輸入命令javac PackageTest.java,編譯第一個(gè)文件,生成PackageTest.class。
編譯第二個(gè)文件
輸入命令javac PackageTest2.java,編譯第二個(gè)文件,卻報(bào)錯(cuò)了:
其實(shí)我們import了啊,但為什么找不到呢?
看錯(cuò)誤原因:程序包c(diǎn)om.hhh.test不存在!
不知道大家在使用Eclipse、IDEA等IDE的時(shí)候記不記得那包結(jié)構(gòu)看起來就是一層一層的“文件夾”?
所以啊,你看看我們這里,哪有個(gè)文件夾嘛?
更正編譯指令,重新編譯程序一
輸入命令javac -d . PackageTest.java,重新編譯第一個(gè)文件,生成包結(jié)構(gòu)的“文件夾”。
我們逐層打開看看是什么樣子:
這才是真正的把包結(jié)構(gòu)弄出來了。
重新編譯程序二
輸入命令javac PackageTest2.java,編譯第二個(gè)文件,生成PackageTest2.class。
使用-d .可以達(dá)到預(yù)期,并且發(fā)現(xiàn)com和hhh果真是合并在一起的,只是test和test2分列兩個(gè)文件夾:
運(yùn)行程序一
如下運(yùn)行,報(bào)錯(cuò),找不到Class文件,無法加載主類(請注意:已編譯完成,所以不要去找.java。JVM解釋執(zhí)行的是.class):
于是想到,實(shí)際上在命令行使用包結(jié)構(gòu)的時(shí)候必須要使用包全名才能執(zhí)行,且不需要跳到.class文件的具體路徑:
運(yùn)行程序二
探究自建文件夾是否有效
我們先不使用-d .,而是進(jìn)行普通的編譯,然后自己新建文件夾,把編譯好的.class放進(jìn)去,再執(zhí)行:
得到了同樣的結(jié)果,也就是可執(zhí)行的,是有效的。
探究拆了文件夾能否執(zhí)行
其實(shí)根據(jù)PackageTest2.java編譯通不過這件事我們就能推測出這肯定不能執(zhí)行,但實(shí)踐出真知嘛:
果然,不行的呢!
對package的思考
package為何而存在
為了更好地組織類,Java 提供了包機(jī)制,用于區(qū)別類名的命名空間。
package的作用
- 把功能相似或相關(guān)的類或接口組織在同一個(gè)包中,方便類的查找和使用。
- 如同文件夾一樣,包也采用了樹形目錄的存儲(chǔ)方式。同一個(gè)包中的類名字是不同的,不同的包中的類的名字是可以相同的,當(dāng)同時(shí)調(diào)用兩個(gè)不同包中相同類名的類時(shí),應(yīng)該加上包名加以區(qū)別。因此,包可以避免名字沖突。
- 包也限定了訪問權(quán)限,擁有包訪問權(quán)限的類才能訪問某個(gè)包中的類。
Java與package
Java 使用包(package)這種機(jī)制是為了防止命名沖突,進(jìn)行訪問控制,便于搜索和定位類(class)、接口(interface)、枚舉(enumeration)和注解(annotation)等。
package既是一種機(jī)制、一種結(jié)構(gòu),也是一個(gè)關(guān)鍵詞。
我們編寫一個(gè)類的時(shí)候,.java源文件的頂部就是package package1[.package2[.package3[…]]];這種語法格式,其中package正是我們說的那個(gè)關(guān)鍵詞。
在導(dǎo)入包的時(shí)候就要用import,語法格式是:import package1[.package2[.package3[…]]].ClassName;。當(dāng)然也有 import static 這種操作,此處就不提了。
使用包結(jié)構(gòu)的內(nèi)在邏輯思考
上面對包的總結(jié),都是一些冠冕堂皇的廢話,我說點(diǎn)實(shí)在的感悟。
想到起初在學(xué)校做課設(shè)項(xiàng)目的時(shí)候,要求使用“三層架構(gòu)”。
由于很多同學(xué)并沒有接觸過這方面的東西,也沒有經(jīng)驗(yàn),所以就不分包或者胡亂分包。更有意思的是有的人為了“得分,分出了.dao、.service、.view等包,實(shí)則毫無邏輯地亂寫一通,只是為了欺騙驗(yàn)收老師多刷點(diǎn)GPA。我們可不能那樣,還是要盡早地去努力理解呀。
包結(jié)構(gòu)不論怎么說,完成了物理結(jié)構(gòu)上的分包,通過把文件分在不同的目錄結(jié)構(gòu),避免了命名沖突。
怎么分呢?其實(shí)背后是邏輯的分層。
我們可以先分層,把不同的層分在不同的包里;再分邏輯,按照業(yè)務(wù)邏輯分出各個(gè)模塊,按照模塊名在表示層的包結(jié)構(gòu)里再分子包。分到這個(gè)程度,才能說基本是分好了包結(jié)構(gòu)。而模塊的劃分,源自對需求和業(yè)務(wù)邏輯的理解,有時(shí)會(huì)分出幾級子模塊。
如果你能理解明白每個(gè)層的作用、明確每個(gè)模塊的劃分,你就能更好地完成包結(jié)構(gòu)劃分了。多看看好的包結(jié)構(gòu)劃分,熟能生巧,你就會(huì)操作了。
其實(shí)這種使用物理分包來完成業(yè)務(wù)邏輯劃分的方式不是那么好,所以就有了Java9的模塊化,包仍然存在,但包不再是業(yè)務(wù)邏輯的唯一劃分了,也會(huì)更好的吧。這方面我也沒什么經(jīng)驗(yàn),就不多說了吧。
總結(jié)
我們使用javac、java命令分別完成了帶有包結(jié)構(gòu)的Java程序的編譯和執(zhí)行,親手操作了一次IDE幫我們省略的工作,雖不復(fù)雜,但很棒的不是嗎?
我們不能只會(huì)使用IDE這種開發(fā)工具,越是強(qiáng)大的IDE,往往越是隱去了更多我們的基本操作,對于掌握知識(shí)未必是好事。
本文的核心是:手把手地教大家使用命令行完成與Java包結(jié)構(gòu)相關(guān)的建構(gòu)、編譯、調(diào)用、運(yùn)行。
文末對package特別是Java的package進(jìn)行了總結(jié),并淺談自己對于包結(jié)構(gòu)的理解。
希望能對大家有所幫助吧!
總結(jié)
以上是生活随笔為你收集整理的【Java】命令行下的Java包结构编译与执行的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【操作系统】大内核和微内核的比较
- 下一篇: 动态规划求解装箱问题(洛谷P1049题题