本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到個人倉庫裏查看html
喜歡的話麻煩點下Star哈git
文章首發於個人我的博客:程序員
www.how2playlife.comgithub
本文是微信公衆號【Java技術江湖】的《夯實Java基礎系列博文》其中一篇,本文部份內容來源於網絡,爲了把本文主題講得清晰透徹,也整合了不少我認爲不錯的技術博客內容,引用其中了一些比較好的博客文章,若有侵權,請聯繫做者。 該系列博文會告訴你如何從入門到進階,一步步地學習Java基礎知識,並上手進行實戰,接着瞭解每一個Java知識點背後的實現原理,更完整地瞭解整個Java技術體系,造成本身的知識框架。爲了更好地總結和檢驗你的學習成果,本系列文章也會提供每一個知識點對應的面試題以及參考答案。面試
若是對本系列文章有什麼建議,或者是有什麼疑問的話,也能夠關注公衆號【Java技術江湖】聯繫做者,歡迎你參與本系列博文的創做和修訂。算法
<!-- more -->shell
Java中的包是封裝一組類,子包和接口的機制。軟件包用於:編程
防止命名衝突。例如,能夠有兩個名稱分別爲Employee的類,college.staff.cse.Employee和college.staff.ee.Employee 更輕鬆地搜索/定位和使用類,接口,枚舉和註釋windows
提供受控訪問:受保護和默認有包級別訪問控制。受保護的成員能夠經過同一個包及其子類中的類訪問。默認成員(沒有任何訪問說明符)只能由同一個包中的類訪問。
包能夠被視爲數據封裝(或數據隱藏)。
咱們所須要作的就是將相關類放入包中。以後,咱們能夠簡單地從現有的軟件包中編寫一個導入類,並將其用於咱們的程序中。一個包是一組相關類的容器,其中一些類能夠訪問,而且其餘類被保存用於內部目的。 咱們能夠在程序中儘量多地重用包中的現有類。
爲了更好地組織類,Java 提供了包機制,用於區別類名的命名空間。
Java 使用包(package)這種機制是爲了防止命名衝突,訪問控制,提供搜索和定位類(class)、接口、枚舉(enumerations)和註釋(annotation)等。
包語句的語法格式爲: package pkg1[.pkg2[.pkg3…]]; 例如,一個Something.java 文件它的內容 package net.java.util; public class Something{ ... }
那麼它的路徑應該是 net/java/util/Something.java 這樣保存的。 package(包) 的做用是把不一樣的 java 程序分類保存,更方便的被其餘 java 程序調用。
一個包(package)能夠定義爲一組相互聯繫的類型(類、接口、枚舉和註釋),爲這些類型提供訪問保護和命名空間管理的功能。
如下是一些 Java 中的包:
開發者能夠本身把一組類和接口等打包,並定義本身的包。並且在實際開發中這樣作是值得提倡的,當你本身完成類的實現以後,將相關的類分組,可讓其餘的編程者更容易地肯定哪些類、接口、枚舉和註釋等是相關的。
因爲包建立了新的命名空間(namespace),因此不會跟其餘包中的任何名字產生命名衝突。使用包這種機制,更容易實現訪問控制,而且讓定位相關類更加簡單。
類放在包中會有兩種主要的結果:
下面是管理你本身 java 中文件的一種簡單方式:
將類、接口等類型的源碼放在一個文本中,這個文件的名字就是這個類型的名字,並以.java做爲擴展名。例如:
// 文件名 : Car.java package vehicle; public class Car { // 類實現 }
接下來,把源文件放在一個目錄中,這個目錄要對應類所在包的名字。
....\vehicle\Car.java
如今,正確的類名和路徑將會是以下樣子:
一般,一個公司使用它互聯網域名的顛倒形式來做爲它的包名.例如:互聯網域名是 runoob.com,全部的包名都以 com.runoob 開頭。包名中的每個部分對應一個子目錄。
例如:有一個 com.runoob.test 的包,這個包包含一個叫作 Runoob.java 的源文件,那麼相應的,應該有以下面的一連串子目錄:
....\com\runoob\test\Runoob.java
編譯的時候,編譯器爲包中定義的每一個類、接口等類型各建立一個不一樣的輸出文件,輸出文件的名字就是這個類型的名字,並加上 .class 做爲擴展後綴。 例如:
// 文件名: Runoob.java package com.runoob.test; public class Runoob { } class Google { }
如今,咱們用-d選項來編譯這個文件,以下:
<pre>$javac -d . Runoob.java</pre>
這樣會像下面這樣放置編譯了的文件:
<pre>.\com\runoob\test\Runoob.class .\com\runoob\test\Google.class</pre>
你能夠像下面這樣來導入全部** \com\runoob\test\ **中定義的類、接口等:
<pre>import com.runoob.test.*;</pre>
編譯以後的 .class 文件應該和 .java 源文件同樣,它們放置的目錄應該跟包的名字對應起來。可是,並不要求 .class 文件的路徑跟相應的 .java 的路徑同樣。你能夠分開來安排源碼和類的目錄。
<pre><path-one>\sources\com\runoob\test\Runoob.java <path-two>\classes\com\runoob\test\Google.class</pre>
這樣,你能夠將你的類目錄分享給其餘的編程人員,而不用透露本身的源碼。用這種方法管理源碼和類文件可讓編譯器和java 虛擬機(JVM)能夠找到你程序中使用的全部類型。
類目錄的絕對路徑叫作 class path。設置在系統變量 CLASSPATH 中。編譯器和 java 虛擬機經過將 package 名字加到 class path 後來構造 .class 文件的路徑。
<path- two>\classes 是 class path,package 名字是 com.runoob.test,而編譯器和 JVM 會在 <path-two>\classes\com\runoob\test 中找 .class 文件。
一個 class path 可能會包含好幾個路徑,多路徑應該用分隔符分開。默認狀況下,編譯器和 JVM 查找當前目錄。JAR 文件按包含 Java 平臺相關的類,因此他們的目錄默認放在了 class path 中。
用下面的命令顯示當前的CLASSPATH變量:
刪除當前CLASSPATH變量內容:
設置CLASSPATH變量:
Java包(package)詳解 java包的做用是爲了區別類名的命名空間
一、把功能類似或相關的類或接口組織在同一個包中,方便類的查找和使用。、
二、如同文件夾同樣,包也採用了樹形目錄的存儲方式。同一個包中的類名字是不一樣的,不一樣的包中的類的名字是能夠相同的,
當同時調用兩個不一樣包中相同類名的類時,應該加上包名加以區別。所以,包能夠避免名字衝突。
三、包也限定了訪問權限,擁有包訪問權限的類才能訪問某個包中的類。
建立包 建立包的時候,你須要爲這個包取一個合適的名字。以後,若是其餘的一個源文件包含了這個包提供的類、接口、枚舉或者註釋類型的時候,都必須將這個包的聲明放在這個源文件的開頭。
包聲明應該在源文件的第一行,每一個源文件只能有一個包聲明,這個文件中的每一個類型都應用於它。
若是一個源文件中沒有使用包聲明,那麼其中的類,函數,枚舉,註釋等將被放在一個無名的包(unnamed package)中。
例子 讓咱們來看一個例子,這個例子建立了一個叫作animals的包。一般使用小寫的字母來命名避免與類、接口名字的衝突。
在 animals 包中加入一個接口(interface):
package animals; interface Animal { public void eat(); public void travel(); }
接下來,在同一個包中加入該接口的實現:
package animals; /* 文件名 : MammalInt.java */ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } }
import 關鍵字 爲了可以使用某一個包的成員,咱們須要在 Java 程序中明確導入該包。使用 "import" 語句可完成此功能。
在 java 源文件中 import 語句應位於 package 語句以後,全部類的定義以前,能夠沒有,也能夠有多條,其語法格式爲:
1 import package1[.package2…].(classname|*); 若是在一個包中,一個類想要使用本包中的另外一個類,那麼該包名能夠省略。
一般,一個公司使用它互聯網域名的顛倒形式來做爲它的包名.例如:互聯網域名是 runoob.com,全部的包名都以 com.runoob 開頭。包名中的每個部分對應一個子目錄。
例如:有一個 com.runoob.test 的包,這個包包含一個叫作 Runoob.java 的源文件,那麼相應的,應該有以下面的一連串子目錄:
1 ....\com\runoob\test\Runoob.java
軟件包的類型有內置的軟件包和用戶定義的軟件包內置軟件包 這些軟件包由大量的類組成,這些類是Java API的一部分。一些經常使用的內置軟件包有:
1)java.lang:包含語言支持類(例如分類,用於定義基本數據類型,數學運算)。該軟件包會自動導入。
2) java.io:包含分類以支持輸入/輸出操做。
3) java.util:包含實現像連接列表,字典和支持等數據結構的實用類; 用於日期/時間操做。
4) java.applet:包含用於建立Applets的類。
5) java.awt:包含用於實現圖形用戶界面組件的類(如按鈕,菜單等)。
6) java.net:包含支持網絡操做的類。
SUN對於dt.jar的定義:Also includes dt.jar, the DesignTime archive of BeanInfo files that tell interactive development environments (IDE's) how to display the Java components and how to let the developer customize them for the application。
中文翻譯過來就是:dt.jar是BeanInfo文件的DesignTime歸檔,BeanInfo文件用來告訴集成開發環境(IDE)如何顯示Java組件還有如何讓開發人員根據應用程序自定義它們。這段文字中提到了幾個關鍵字:DesignTime,BeanInfo,IDE,Java components。其實dt.jar就是DesignTime Archive的縮寫。那麼何爲DesignTime。
何爲DesignTime?翻譯過來就是設計時。其實瞭解JavaBean的人都知道design time和runtime(運行時)這兩個術語的含義。設計時(DesignTIme)是指在開發環境中經過添加控件,設置控件或窗體屬性等方法,創建應用程序的時間。
與此相對應的運行時(RunTIme)是指能夠象用戶那樣與應用程序交互做用的時間。那麼如今再理解一下上面的翻譯,其實dt.jar包含了swing控件中的BeanInfo,而IDE的GUI Designer須要這些信息。那讓咱們看一下dt.jar中到底有什麼?下面是一張dt.jar下面的內容截圖:
從上面的截圖能夠看出,dt.jar中所有是Swing組件的BeanInfo。那麼到底什麼是BeanInfo呢?
何爲BeanInfo?JavaBean和BeanInfo有很大的關係。Sun所制定的JavaBean規範,很大程度上是爲IDE準備的——它讓IDE可以以可視化的方式設置JavaBean的屬性。若是在IDE中開發一個可視化應用程序,咱們須要經過屬性設置的方式對組成應用的各類組件進行定製,IDE經過屬性編輯器讓開發人員使用可視化的方式設置組件的屬性。
通常的IDE都支持JavaBean規範所定義的屬性編輯器,當組件開發商發佈一個組件時,它每每將組件對應的屬性編輯器捆綁發行,這樣開發者就能夠在IDE環境下方便地利用屬性編輯器對組件進行定製工做。JavaBean規範經過java.beans.PropertyEditor定義了設置JavaBean屬性的方法,經過BeanInfo描述了JavaBean哪些屬性是可定製的,此外還描述了可定製屬性與PropertyEditor的對應關係。
BeanInfo與JavaBean之間的對應關係,經過二者之間規範的命名確立:對應JavaBean的BeanInfo採用以下的命名規範:<Bean>BeanInfo。當JavaBean連同其屬性編輯器相同的組件註冊到IDE中後,當在開發界面中對JavaBean進行定製時,IDE就會根據JavaBean規範找到對應的BeanInfo,再根據BeanInfo中的描述信息找到JavaBean屬性描述(是否開放、使用哪一個屬性編輯器),進而爲JavaBean生成特定開發編輯界面。
dt.jar裏面主要是swing組件的BeanInfo。IDE根據這些BeanInfo顯示這些組件以及開發人員如何定製他們。
rt.jar是runtime的歸檔。Java基礎類庫,也就是Java doc裏面看到的全部的類的class文件。
rt.jar 默認就在Root Classloader的加載路徑裏面的,而在Claspath配置該變量是不須要的;同時jre/lib目錄下的其餘jar:jce.jar、jsse.jar、charsets.jar、resources.jar都在Root Classloader中。
.java文件你能夠認爲只是一個文本文件, 這個文件便是用java語言寫成的程序,或者說任務的代碼塊。
.class文件本質上是一種二進制文件, 它通常是由.java文件經過 javac這個命令(jdk自己提供的工具)生成的一個文件, 而這個文件能夠由jvm(java虛擬機)裝載(類裝載),而後進java解釋執行, 這也就是運行你的程序。
你也能夠這樣比較一下: .java與 .c , .cpp, .asm等等文件,本質 上同樣的, 只是用一種 語言來描述你要怎麼去完成一件事(一個任務), 而這種語言 計算機自己 是沒有辦法知道是什麼含義的, 它面向的只是程序員自己, 程序員能夠經過 語言自己(語法) 來描述或組織這個任務,這也就 是所謂的編程。
最後你固然是須要計算機按照你的意圖來運行你的程序, 這時候就先得有一個翻譯(編譯, 彙編, 連接等等複雜的過程)把它變成機器可理解的指令(這就是你們說的機器語言,機器語言自己也是一種編程語言,只是程序很難寫,很難讀懂,基本上沒有辦法維護)。
這裏的.class文件在計算的體系結構中本質上對應的是一種機器語言(而這裏的機器叫做JVM),因此JVM自己是能夠直接運行這裏的.class文件。因此 你能夠進一步地認爲,.java與.class與其它的編程語法同樣,它們都是程序員用來描述本身的任務的一種語言,只是它們面向的對象不同,而計算機自己只能識別它自已定義的那些指令什麼的(再次強調,這裏的計算機自己沒有那麼嚴格的定義)
In short:
.java是Java的源文件後綴,裏面存放程序員編寫的功能代碼。
.class文件是字節碼文件,由.java源文件經過javac命令編譯後生成的文件。是能夠運行在任何支持Java虛擬機的硬件平臺和操做系統上的二進制文件。
.class文件並不本地的可執行程序。Java虛擬機就是去運行.class文件從而實現程序的運行。
在java編程思想(第四版)一書中有這樣3段話(6.4 類的訪問權限):
1.每一個編譯單元(文件)都只能有一個public類,這表示,每一個編譯單元都有單一的公共接口,用public類來表現。該接口能夠按要求包含衆多的支持包訪問權限的類。若是在某個編譯單元內有一個以上的public類,編譯器就會給出錯誤信息。
2.public類的名稱必須徹底與含有該編譯單元的文件名相同,包含大小寫。若是不匹配,一樣將獲得編譯錯誤。
3.雖然不是很經常使用,但編譯單元內徹底不帶public類也是可能的。在這種狀況下,能夠隨意對文件命名。
總結相關的幾個問題:
一、一個」.java」源文件中是否能夠包括多個類(不是內部類)?有什麼限制?
答:能夠有多個類,但只能有一個public的類,而且public的類名必須與文件名相一致。
二、爲何一個文件中只能有一個public的類
答:編譯器在編譯時,針對一個java源代碼文件(也稱爲「編譯單元」)只會接受一個public類。不然報錯。
三、在java文件中是否能夠沒有public類
答:public類不是必須的,java文件中能夠沒有public類。
四、爲何這個public的類的類名必須和文件名相同
答: 是爲了方便虛擬機在相應的路徑中找到相應的類所對應的字節碼文件。
主函數:是一個特殊的函數,做爲程序的入口,能夠被JVM調用
主函數的定義:
public:表明着該函數訪問權限是最大的
static:表明主函數隨着類的加載就已經存在了
void:主函數沒有具體的返回值
main:不是關鍵字,可是一個特殊的單詞,可以被JVM識別
(String[] args):函數的參數,參數類型是一個數組,該數組中的元素師字符串,字符串數組。main(String[] args) 字符串數組的 此時空數組的長度是0,但也能夠在 運行的時候向其中傳入參數。
主函數時固定格式的,JVM識別
主函數能夠被重載,可是JVM只識別main(String[] args),其餘都是做爲通常函數。這裏面的args知識數組變量能夠更改,其餘都不能更改。
一個java文件中能夠包含不少個類,每一個類中有且僅有一個主函數,可是每一個java文件中能夠包含多個主函數,在運行時,須要指定JVM入口是哪一個。例如一個類的主函數能夠調用另外一個類的主函數。不必定會使用public類的主函數。
外部類只能用public和default修飾。
爲何要對外部類或類作修飾呢?
1.存在包概念:public 和 default 能區分這個外部類能對不一樣包做一個劃分 (default修飾的類,其餘包中引入不了這個類,public修飾的類才能被import)
2.protected是包內可見而且子類可見,可是當一個外部類想要繼承一個protected修飾的非同包類時,壓根找不到這個類,更別提幾層了
3.private修飾的外部類,其餘任何外部類都沒法導入它。
//Java中的文件名要和public修飾的類名相同,不然會報錯 //若是沒有public修飾的類,則文件能夠隨意命名 public class Java中的類文件 { } //非公共開類的訪問權限默認是包訪問權限,不能用private和protected //一個外部類的訪問權限只有兩種,一種是包內可見,一種是包外可見。 //若是用private修飾,其餘類根本沒法看到這個類,也就沒有意義了。 //若是用protected,雖然也是包內可見,可是若是有子類想要繼承該類可是不一樣包時, //壓根找不到這個類,也不可能繼承它了,因此乾脆用default代替。 class A{ }
以 java.* 開頭的是Java的核心包,全部程序都會使用這些包中的類;
以 javax.* 開頭的是擴展包,x 是 extension 的意思,也就是擴展。雖然 javax.* 是對 java.* 的優化和擴展,可是因爲 javax.* 使用的愈來愈多,不少程序都依賴於 javax.,因此 javax. 也是核心的一部分了,也隨JDK一塊兒發佈。
以 org.* 開頭的是各個機構或組織發佈的包,由於這些組織頗有影響力,它們的代碼質量很高,因此也將它們開發的部分經常使用的類隨JDK一塊兒發佈。
在包的命名方面,爲了防止重名,有一個慣例:你們都以本身域名的倒寫形式做爲開頭來爲本身開發的包命名,例如百度發佈的包會以 com.baidu.* 開頭,w3c組織發佈的包會以 org.w3c.* 開頭,微學苑發佈的包會以 net.weixueyuan.* 開頭……
組織機構的域名後綴通常爲 org,公司的域名後綴通常爲 com,能夠認爲 org.* 開頭的包爲非盈利組織機構發佈的包,它們通常是開源的,能夠無償使用在本身的產品中,不用考慮侵權問題,而以 com.* 開頭的包每每由盈利性的公司發佈,可能會有版權問題,使用時要注意。
http://www.javashuo.com/article/p-sctyzhnt-cz.html https://blog.csdn.net/fuhanghang/article/details/84102404 https://www.runoob.com/java/java-package.html https://www.breakyizhan.com/java/4260.html https://blog.csdn.net/qq_36626914/article/details/80627454
若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人公衆號【Java技術江湖】一位阿里 Java 工程師的技術小站,做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!
Java工程師必備學習資源: 一些Java工程師經常使用學習資源,關注公衆號後,後臺回覆關鍵字 「Java」 便可免費無套路獲取。
做者是 985 碩士,螞蟻金服 JAVA 工程師,專一於 JAVA 後端技術棧:SpringBoot、MySQL、分佈式、中間件、微服務,同時也懂點投資理財,偶爾講點算法和計算機理論基礎,堅持學習和寫做,相信終身學習的力量!
程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取。
原文出處:https://www.cnblogs.com/AliCoder/p/11595349.html