V mojom predchádzajúcom Java 101 v tomto výučbe ste sa naučili, ako lepšie usporiadať svoj kód vyhlásením referenčných typov (tiež známych ako triedy a rozhrania) za členov iných referenčných typov a blokov. Tiež som vám ukázal, ako pomocou vnorenia zabrániť konfliktom názvov medzi vnorenými referenčnými typmi a referenčnými typmi najvyššej úrovne, ktoré zdieľajú rovnaký názov.
Spolu s vnorením Java používa balíčky na riešenie problémov s rovnakým menom v referenčných typoch najvyššej úrovne. Používanie statických importov tiež zjednodušuje prístup k statickým členom v zabalených referenčných typoch najvyššej úrovne. Statické importy vám ušetria stlačenia klávesov pri prístupe k týmto členom vo vašom kóde, ale pri ich použití je potrebné si dať pozor na niekoľko vecí. V tomto návode vás oboznámim s používaním balíkov a statických importov vo vašich programoch Java.
stiahnuť Získajte kód Stiahnite si zdrojový kód napríklad pre aplikácie v tomto výučbe Java. Vytvoril Jeff Friesen pre JavaWorld.Referenčné typy balenia
Vývojári Java zoskupujú súvisiace triedy a rozhrania do balíkov. Používanie balíkov uľahčuje vyhľadanie a použitie referenčných typov, predchádzanie konfliktom názvov medzi rovnako pomenovanými typmi a riadenie prístupu k typom.
V tejto časti sa dozviete o balíkoch. Dozviete sa, čo sú to balíčky, dozviete sa viac o balíček
a dovoz
vyhlásenia a preskúmajte ďalšie témy chráneného prístupu, súborov JAR a hľadania typov.
Čo sú balíky v Jave?
Pri vývoji softvéru bežne organizujeme položky podľa ich hierarchických vzťahov. Napríklad v predchádzajúcom tutoriáli som vám ukázal, ako deklarovať triedy ako členov iných tried. Môžeme tiež použiť súborové systémy na vnorenie adresárov do iných adresárov.
Používanie týchto hierarchických štruktúr vám pomôže vyhnúť sa konfliktom mien. Napríklad v nehierarchickom systéme súborov (jeden adresár) nie je možné priradiť rovnaký názov viacerým súborom. Naproti tomu hierarchický súborový systém umožňuje, aby súbory s rovnakým názvom existovali v rôznych adresároch. Podobne dve uzatvárajúce triedy môžu obsahovať vnorené triedy s rovnakým názvom. Konflikty mien neexistujú, pretože položky sú rozdelené do rôznych menných priestorov.
Java nám tiež umožňuje rozdeliť referenčné typy na najvyššej úrovni (vnorené) do viacerých menných priestorov, aby sme mohli lepšie usporiadať tieto typy a zabrániť konfliktom mien. V prostredí Java používame funkciu balíkového jazyka na rozdelenie referenčných typov najvyššej úrovne do viacerých menných priestorov. V takom prípade a balíček je jedinečný menný priestor na ukladanie referenčných typov. Balíky môžu ukladať triedy a rozhrania, ako aj podbalenia, čo sú balíčky vnorené do iných balíkov.
Balík má názov, ktorý musí byť nevyhradeným identifikátorom; napríklad, java
. Operátor prístupu členov (.
) oddeľuje názov balíka od názvu podbalenia a oddeľuje názov balíka alebo podbalenia od názvu typu. Napríklad dvojčlenní operátori prístupu v java.lang.System
názov samostatného balíka java
z lang
názov podbalenia a samostatný názov podbalenia lang
z Systém
zadajte názov.
Musia sa deklarovať referenčné typy verejné
aby boli prístupné z vonkajšej strany ich balíkov. To isté platí pre všetky konštanty, konštruktory, metódy alebo vnorené typy, ktoré musia byť prístupné. Ich príklady uvidíte ďalej v tomto výučbe.
Vyhlásenie o balíku
V Jave používame vyhlásenie o balíku vytvoriť balíček. Toto vyhlásenie sa nachádza v hornej časti zdrojového súboru a identifikuje balík, do ktorého patria typy zdrojových súborov. Musí vyhovovať nasledujúcej syntaxi:
balíček identifikátor[.identifikátor]*;
Výpis balíka sa začína rezervovaným slovom balíček
a pokračuje identifikátorom, za ktorým prípadne nasleduje periodicky oddelená sekvencia identifikátorov. Bodkočiarka (;
) ukončuje toto vyhlásenie.
Prvý (najviac vľavo) identifikátor pomenuje balík a každý nasledujúci identifikátor pomenuje čiastkový balík. Napríklad v balíček a.b;
, všetky typy deklarované v zdrojovom súbore patria do b
podbal a
balíček.
Konvencia pomenovania balíkov / podbalení
Podľa konvencie vyjadrujeme názov balíka alebo podbalenia malými písmenami. Ak sa názov skladá z viacerých slov, možno budete chcieť písať veľké písmená okrem prvého; napríklad, generalLedger
.
Postupnosť názvov balíkov musí byť jedinečná, aby sa zabránilo problémom s kompiláciou. Predpokladajme napríklad, že vytvoríte dva rôzne grafika
balíkov a predpokladajme, že každý z nich grafika
balenie obsahuje a Trojuholník
triedy s iným rozhraním. Keď sa kompilátor Java stretne s niečím podobným, musí overiť, či Trojuholník (int, int, int, int)
konštruktor existuje:
Trojuholník t = nový trojuholník (1, 20, 30, 40);
Ohraničujúca skrinka trojuholníka
Pomysli na Trojuholník
konštruktor ako určujúci ohraničujúci rámček, v ktorom má byť nakreslený trojuholník. Prvé dva parametre identifikujú ľavý horný roh boxu a druhé dva parametre definujú rozsah boxu.
Kompilátor prehľadá všetky prístupné balíky, kým nenájde a grafika
balíček, ktorý obsahuje a Trojuholník
trieda. Ak nájdený balík obsahuje príslušné Trojuholník
trieda s a Trojuholník (int, int, int, int)
konštruktér, všetko je v poriadku. V opačnom prípade, ak sa nájde Trojuholník
trieda nemá Trojuholník (int, int, int, int)
konštruktor, kompilátor nahlási chybu. (Viac o vyhľadávacom algoritme poviem ďalej v tomto tutoriále.)
Tento scenár ilustruje dôležitosť výberu jedinečných sekvencií názvov balíkov. Konvenciou pri výbere jedinečnej postupnosti mien je obrátiť názov svojej internetovej domény a použiť ho ako predponu pre postupnosť. Napríklad by som si vybral ca.javajeff
ako moja predpona, pretože javajeff.ca
je moje doménové meno. Potom by som upresnil ca.javajeff.graphics.Triangle
pristúpiť Trojuholník
.
Komponenty doménových mien a platné názvy balíkov
Komponenty doménových mien nie sú vždy platné názvy balíkov. Jeden alebo viac názvov komponentov môže začínať číslicou (3D.com
), obsahujú pomlčku (-
) alebo iný nezákonný znak (ab-z.com
), alebo byť jedným z vyhradených slov Java (short.com
). Konvencia diktuje, aby ste pred číslicu dali predponu (com._3D
), nahraďte nelegálny znak podčiarkovníkom (com.ab_z
) a doplňte vyhradené slovo podčiarknutím (com.short_
).
Musíte sa držať niekoľkých pravidiel, aby ste sa vyhli ďalším problémom s výpisom balíka:
- V zdrojovom súbore môžete deklarovať iba jeden výpis balíka.
- Vyhláseniu o balíku nemôžete okrem komentárov nič predchádzať.
Prvé pravidlo, ktoré je zvláštnym prípadom druhého pravidla, existuje, pretože nemá zmysel ukladať referenčný typ do viacerých balíkov. Aj keď do balíka možno uložiť viac typov, typ môže patriť iba do jedného balíka.
Ak zdrojový súbor nedeklaruje príkaz balíka, o zdrojových súboroch sa hovorí, že patria k súboru nepomenovaný balík. Netriviálne referenčné typy sú zvyčajne uložené v ich vlastných balíkoch a vyhýbajú sa nepomenovaným balíkom.
Implementácie Java mapujú názvy balíkov a čiastkových balíkov na adresáre s rovnakým názvom. Napríklad implementácia by mapovala grafika
do adresára s názvom grafika
. V prípade balíka a.b
, prvé písmeno, a namapuje na adresár s názvom a
a b by mapoval na a b
podadresár a
. Kompilátor ukladá súbory triedy, ktoré implementujú typy balíka, do zodpovedajúceho adresára. Nepomenovaný balík zodpovedá aktuálnemu adresáru.
Príklad: Balenie zvukovej knižnice v prostredí Java
Praktický príklad je užitočný na úplné pochopenie balíček
vyhlásenie. V tejto časti demonštrujem balíky v kontexte zvukovej knižnice, ktorá vám umožňuje čítať zvukové súbory a získavať zvukové údaje. Pre stručnosť uvediem iba skeletovú verziu knižnice.
Audioknižnica v súčasnosti pozostáva iba z dvoch tried: Zvuk
a WavReader
. Zvuk
popisuje zvukový klip a je hlavnou triedou knižnice. Zoznam 1 predstavuje zdrojový kód.
Zoznam 1. Príklad výpisu balíka (Audio.java)
balíček ca.javajeff.audio; verejné záverečné triedy Audio {private int [] vzorky; private int sampleRate; Audio (int [] samples, int sampleRate) {this.samples = samples; this.sampleRate = sampleRate; } public int [] getSamples () {vrátiť vzorky; } public int getSampleRate () {návrat sampleRate; } verejné statické Zvuk newAudio (názov súboru reťazca) {if (názov súboru.toLowerCase (). endsWith (". wav")) vrátiť WavReader.read (názov súboru); else return null; // nepodporovaný formát } }
Prejdime si výpis 1 krok za krokom.
- The
Audio.java
súbor v zozname 1 ukladá súboryZvuk
trieda. Tento zoznam začína výpisom balíka, ktorý identifikujeca.javajeff.audio
ako balíček triedy. Zvuk
je vyhlásenýverejné
aby na ne bolo možné odkazovať aj mimo jej balíka. Tiež je to deklarovanékonečné
aby ho nebolo možné rozšíriť (to znamená podtriedu).Zvuk
vyhlasujesúkromné
vzorky
asampleRate
polia na ukladanie zvukových údajov. Tieto polia sú inicializované na hodnoty odovzdanéZvuk
konštruktér.Zvuk
je deklarovaný konštruktor balík-súkromné (to znamená, že konštruktor nie je deklarovanýverejné
,súkromné
alebochránené
), takže túto triedu nie je možné vytvoriť mimo balíka.Zvuk
darčekygetSamples ()
agetSampleRate ()
metódy vrátenia vzoriek zvukového klipu a vzorkovacej frekvencie. Každá metóda je deklarovanáverejné
aby sa dalo volať zvonkuZvuk
balíček.Zvuk
uzatvára averejné
astatický
newAudio ()
továrenská metóda vráteniaZvuk
objekt zodpovedajúcinázov súboru
argument. Ak nie je možné získať zvukový klip,nulový
sa vracia.newAudio ()
porovnávanázov súboru
rozšírenie s.wav
(tento príklad podporuje iba zvuk WAV). Ak sa zhodujú, vykoná savrátiť WavReader.read (názov súboru)
vrátiťZvuk
objekt so zvukovými dátami založenými na WAV.
Výpis 2 popisuje WavReader
.
Zoznam 2. Trieda pomocníka WavReader (WavReader.java)
balíček ca.javajeff.audio; finálna trieda WavReader {statické načítanie zvuku (názov súboru reťazca) {// Prečítajte si obsah súboru súboru a spracujte ho // do poľa vzorových hodnôt a vzorkovacej frekvencie // hodnoty. Ak súbor nie je možné prečítať, vráťte hodnotu null. Pre // stručnosť (a pretože som ešte nediskutoval o Java // súborových I / O API) uvádzam iba kostrový kód, ktorý // vždy vráti audio objekt s predvolenými hodnotami. vrátiť nové audio (new int [0], 0); }}
WavReader
je určený na načítanie obsahu súboru WAV do formátu Zvuk
objekt. (Trieda bude nakoniec väčšia s ďalšími súkromné
polia a metódy.) Všimnite si, že táto trieda nie je deklarovaná verejné
, čo robí WavReader
prístupné pre Zvuk
ale nie na kódovanie mimo ca.javajeff.audio
balíček. Rozmýšľať o WavReader
ako pomocná trieda, ktorej jediným dôvodom existencie je slúžiť Zvuk
.
Ak chcete vytvoriť túto knižnicu, postupujte takto:
- Vyberte vhodné umiestnenie vo vašom súborovom systéme ako aktuálny adresár.
- Vytvor
ca / javajeff / audio
hierarchia podadresárov v aktuálnom adresári. - Skopírujte výpisy 1 a 2 do súborov
Audio.java
aWavReader.java
, v uvedenom poradí; a uložiť tieto súbory doaudio
podadresár. - Za predpokladu, že aktuálny adresár obsahuje
ca.
podadresár, vykonaťjavac ca / javajeff / audio / *. java
skompilovať dva zdrojové súbory vo formáteca / javajeff / audio
. Ak všetko pôjde dobre, mali by ste objaviťAudio.trieda
aTrieda WavReader
súbory vaudio
podadresár. (Prípadne v tomto príklade môžete prepnúť naaudio
podadresár a vykonaťjavac * .java
.)
Teraz, keď ste vytvorili zvukovú knižnicu, budete ju chcieť používať. Čoskoro sa pozrieme na malú aplikáciu Java, ktorá demonštruje túto knižnicu. Najprv sa musíte dozvedieť viac o príkaze na import.
Vyhlásenie o importe Javy
Predstavte si, že to musíte špecifikovať ca.javajeff.graphics.Triangle
pre každý výskyt Trojuholník
v zdrojovom kóde opakovane. Java poskytuje príkaz na import ako pohodlnú alternatívu na vynechanie zdĺhavých podrobností balíka.
Vyhlásenie o dovoze importuje typy z balíka tak, že kompilátoru oznámi, kde má hľadať nekvalifikovaný (bez predpony balíka) názvy typov počas kompilácie. Nachádza sa v hornej časti zdrojového súboru a musí zodpovedať nasledujúcej syntaxi:
dovoz identifikátor[.identifikátor]*.(typeName | *);
Výpis importu začína vyhradeným slovom dovoz
a pokračuje identifikátorom, za ktorým prípadne nasleduje periodicky oddelená sekvencia identifikátorov. Meno typu alebo hviezdička (*
) a bodkočiarka ukončí tento príkaz.
Syntax odhaľuje dve formy príkazu na import. Najskôr môžete importovať jeden názov typu, ktorý je identifikovaný pomocou typeName
. Po druhé, môžete importovať všetky typy, ktoré sú označené hviezdičkou.
The *
symbol je zástupný znak, ktorý predstavuje všetky názvy nekvalifikovaného typu. Povie kompilátoru, aby tieto názvy hľadal v balíku úplne vpravo v postupnosti balíka príkazu importu, pokiaľ sa názov typu nenájde v predtým prehľadávanom balíku. Upozorňujeme, že použitie zástupného znaku nemá výkonnostný trest ani nevedie k nafúknutiu kódu. Môže to však viesť k konfliktom mien, ktoré uvidíte.
Napríklad, import ca.javajeff.graphics.Triangle;
hovorí kompilátoru, že nekvalifikovaný Trojuholník
trieda existuje v ca.javajeff.graphics
balíček. Podobne niečo ako
import ca.javajeff.graphics. *;
povie kompilátoru, aby sa pozrel do tohto balíka, keď narazí na a Trojuholník
meno, a Kruh
meno, alebo dokonca Účet
meno (ak Účet
ešte nebol nájdený).
Vyhnite sa * v projektoch pre viacerých vývojárov
Ak pracujete na projekte viacerých vývojárov, nepoužívajte *
zástupný znak, aby ostatní vývojári mohli ľahko zistiť, ktoré typy sa používajú vo vašom zdrojovom kóde.