Programovanie

Balíky a statické importy v Jave

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:

  1. V zdrojovom súbore môžete deklarovať iba jeden výpis balíka.
  2. 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úbory Zvuk trieda. Tento zoznam začína výpisom balíka, ktorý identifikuje ca.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 vyhlasuje súkromnévzorky a sampleRate polia na ukladanie zvukových údajov. Tieto polia sú inicializované na hodnoty odovzdané Zvukkonštruktér.
  • Zvukje deklarovaný konštruktor balík-súkromné (to znamená, že konštruktor nie je deklarovaný verejné, súkromnéalebo chránené), takže túto triedu nie je možné vytvoriť mimo balíka.
  • Zvuk darčeky getSamples () a getSampleRate () metódy vrátenia vzoriek zvukového klipu a vzorkovacej frekvencie. Každá metóda je deklarovaná verejné aby sa dalo volať zvonku Zvukbalíček.
  • Zvuk uzatvára a verejné a statickýnewAudio () továrenská metóda vrátenia Zvuk objekt zodpovedajúci názov súboru argument. Ak nie je možné získať zvukový klip, nulový sa vracia.
  • newAudio () porovnáva názov súborurozšírenie s .wav (tento príklad podporuje iba zvuk WAV). Ak sa zhodujú, vykoná sa vrá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:

  1. Vyberte vhodné umiestnenie vo vašom súborovom systéme ako aktuálny adresár.
  2. Vytvor ca / javajeff / audio hierarchia podadresárov v aktuálnom adresári.
  3. Skopírujte výpisy 1 a 2 do súborov Audio.java a WavReader.java, v uvedenom poradí; a uložiť tieto súbory do audio podadresár.
  4. Za predpokladu, že aktuálny adresár obsahuje ca. podadresár, vykonať javac ca / ​​javajeff / audio / *. java skompilovať dva zdrojové súbory vo formáte ca / javajeff / audio. Ak všetko pôjde dobre, mali by ste objaviť Audio.trieda a Trieda WavReader súbory v audio podadresár. (Prípadne v tomto príklade môžete prepnúť na audio 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.

$config[zx-auto] not found$config[zx-overlay] not found