Hvorfor gjenoppfinne hjulet? Denne klisjeen gjelder programvareutvikling der noen utviklere ofte skriver om den samme koden for forskjellige programmer. To ulemper med den tilnærmingen er:
- Det kaster bort tid
- Det introduserer potensialet for feil i feilsøkt kode
Som et alternativ til omskriving av samme kode, gir mange programvareutviklingsmiljøer et biblioteksverktøy som organiserer ofte brukt kode. Når utviklere er ferdig med feilsøking av en gjenbrukbar kode, bruker de verktøyet til å lagre den koden i en bibliotek—En eller flere filer som inneholder ofte brukt kode for bruk i forskjellige programmer. Under programbygging får kompilatoren eller biblioteksverktøyet tilgang til biblioteket for å koble programmets bibliotekhenviste kode til programmet.
Biblioteker er grunnleggende for Java. De tillater delvis JVMs klasselaster å finne klassefiler. (Jeg vil utforske klasselastere i en fremtidig artikkel.) Av den grunn er Java's biblioteker ofte kjent som klassebiblioteker. Imidlertid refererer Java til klassebiblioteker som pakker.
Denne artikkelen utforsker pakker; Jeg viser deg hvordan du lager pakker med klasser og grensesnitt, hvordan du importerer (det vil si bringe inn i et program) pakkede klasser og grensesnitt, hvordan du flytter pakker på harddisken, og hvordan du bruker jar-filer til å kapsle inn pakker.
Merk |
---|
Denne artikkelens enkeltpakkeeksperiment er Microsoft Windows-spesifikt. Du burde være i stand til enkelt å ekstrapolere dette eksperimentet til ikke-Windows-plattformer. |
Hva er pakker?
EN pakke er en samling av klasser og grensesnitt. Hver pakke har sitt eget navn og organiserer klassene og grensesnittene på toppnivå (dvs. ikke-nestede) i et eget navneområde, eller navnesamling. Selv om samme navngitte klasser og grensesnitt ikke kan vises i samme pakke, kan de vises i forskjellige pakker fordi et eget navneområde tildeles hver pakke.
Fra et implementeringsperspektiv viser det seg nyttig å sidestille en pakke med en katalog, og det samme som å ligne en pakkes klasser og grensesnitt med klassefilene til en katalog. Husk andre tilnærminger - for eksempel bruk av databaser - for å implementere pakker, så ikke vær vane med å alltid sidestille pakker med kataloger. Men fordi mange JVM-er bruker kataloger for å implementere pakker, tilsvarer denne artikkelen pakker med kataloger. Java 2 SDK organiserer sin enorme samling av klasser og grensesnitt i et trelignende hierarki av pakker i pakker, som tilsvarer kataloger i kataloger. Dette hierarkiet gjør at Sun Microsystems enkelt kan distribuere (og du enkelt arbeide med) disse klassene og grensesnittene. Eksempler på Java-pakker inkluderer:
java.lang:
En samling av språkrelaterte klasser, som f.eksGjenstand
ogString
, organisert ijava
pakken erlang
underpakkejava.lang.ref:
En samling referanserelaterte språkkurs, for eksempelSoftReference
ogReferenceQueue
, organisert iref
del-underpakning avjava
pakken erlang
underpakkejavax.swing:
En samling av Swing-relaterte komponentklasser, for eksempelJButton
, og grensesnitt, for eksempelButtonModel
, organisert ijavax
pakken ersvinge
underpakke
Periodekarakterer skiller pakkenavn. For eksempel i javax.swing
, et periodetegn skiller pakkenavnet javax
fra underpakkenavn svinge
. En periodekarakter er den plattformuavhengige ekvivalenten av skråstrek-tegn (/
), tilbakeslagstegn (\
), eller andre tegn for å skille katalognavn i en katalogbasert pakkeimplementering, databasegrener i en hierarkisk databasebasert pakkeimplementering, og så videre.
Tips |
---|
Akkurat som du ikke kan lagre både en fil og en katalog med identiske navn i samme katalog, kan du ikke lagre en klasse eller et grensesnitt og en pakke med identiske navn i samme pakke. For eksempel gitt en pakke som heter kontoer , kan du ikke lagre både en pakke og en klasse som heter som skal betales i kontoer . For å unngå motstridende navn, store bokstaver i klasse- og grensesnittnavn, og små bokstaver i pakkenavn. Ved hjelp av forrige eksempel, butikklasse Som skal betales i pakke kontoer som kontoer. betales og pakke som skal betales i pakke kontoer som kontoer. betalbar . Lær mer om dette og andre navnekonvensjoner fra Suns Kodekonvensjoner for Java-programmeringsspråket. |
Lag en pakke med klasser og grensesnitt
Hver kildefils klasser og grensesnitt organiseres i en pakke. I pakke
direktivets fravær, de klassene og grensesnittene tilhører den ikke-navngitte pakken (katalogen JVM anser som den nåværende katalogen - katalogen der et Java-program begynner å kjøre det via Windows java.exe
, eller OS-ekvivalent, program — og inneholder ingen underpakker). Men hvis den pakke
direktivet vises i en kildefil, det direktivet navngir pakken for disse klassene og grensesnittene. Bruk følgende syntaks til å spesifisere en pakke
direktiv i kildekode:
'pakke' packageName [ '.' underpakkenavn ... ] ';'
EN pakke
direktivet begynner med pakke
nøkkelord. En identifikator som navngir en pakke, packageName
, følger umiddelbart. Hvis klasser og grensesnitt skal vises i en underpakke (på et eller annet nivå) innenfor packageName
, en eller flere periodeseparerte underpakkenavn
identifikatorer vises etter packageName
. Følgende kodefragment presenterer et par pakke
direktiver:
pakke spill; pakke spill. enheter;
Den første pakke
direktivet identifiserer en pakke som heter spill
. Alle klasser og grensesnitt som vises i direktivets kildefil, organiseres i spill
pakke. Den andre pakke
direktivet identifiserer en navngitt delpakke enheter
, som ligger i en pakke som heter spill
. Alle klasser og grensesnitt som vises i direktivets kildefil, organiseres i spill
pakken er enheter
underpakke. Hvis en JVM-implementering tilordner pakkenavn til katalognavn, spill. enheter
kart til en spill \ enheter
kataloghierarki under Windows og a spill / enheter
kataloghierarki under Linux eller Solaris.
Forsiktighet |
---|
Bare en pakke direktivet kan vises i en kildefil. Videre er den pakke direktivet må være den første koden (bortsett fra kommentarer) i den filen. Brudd på en av reglene får Java-kompilatoren til å rapportere en feil. |
For å hjelpe deg med å bli komfortabel med pakker, har jeg utarbeidet et eksempel som spenner over alle emnene i denne artikkelen. I denne delen lærer du hvordan du lager eksemplets pakke. I senere seksjoner vil du lære hvordan du importerer en klasse og et grensesnitt fra denne pakken, hvordan du flytter denne pakken til et annet sted på harddisken og fremdeles får tilgang til pakken fra et program, og hvordan du lagrer pakken i en jar-fil . Oppføring 1 presenterer pakkens kildekode:
Oppføring 1. A.java
// A.java-pakke testpkg; offentlig klasse A {int x = 1; offentlig int y = 2; beskyttet int z = 3; int returnx () {return x; } public int returny () {return y; } beskyttet int returnz () {return z; } offentlig grensesnitt StartStop {ugyldig start (); ugyldig stopp (); }} klasse B {offentlig statisk tomrom hallo () {System.out.println ("hei"); }}
Oppføring 1 introduserer kildekoden til den først navngitte pakken. De pakke testpkg;
direktivet navngir den pakken testpkg
. Innenfor testpkg
er klasser EN
og B
. Innenfor EN
er tre feltdeklarasjoner, tre metodedeklarasjoner og en indre grensesnitterklæring. Innenfor B
er en enkeltmetodedeklarasjon. Hele kildekoden lagres i A.java
fordi EN
er en offentlig klasse. Vår oppgave: Gjør denne kildekoden til en pakke som består av to klasser og et indre grensesnitt (eller en katalog som inneholder tre klassefiler). Følgende Windows-spesifikke trinn utfører den oppgaven:
- Åpne et Windows-kommandovindu og sørg for at du er i
c:
stasjonens rotkatalog (hovedkatalogen — representert med et innledende tilbakeslag\
) karakter). For å gjøre det, skriv innc:
kommando etterfulgt avcd \
kommando. (Hvis du bruker en annen stasjon, bytt utc:
med den valgte stasjonen. Ikke glem å trykke Enter når du har skrevet en kommando.) - Lage en
testpkg
katalog ved å skrivemd testpkg
. Merk: Når du følger trinnene i denne artikkelen, må du ikke skrive perioder etter kommandoene. - Gjøre
testpkg
gjeldende katalog ved å skrivecd testpkg
. - Bruk en redaktør til å angi Listing 1's kildekode og lagre den koden til en
A.java
fil itestpkg
. - Kompilere
A.java
ved å skrivejavac A.java
. Du bør se klassefilerEn $ StartStop.-klasse
,En klasse
, ogB. klasse
vises itestpkg
katalog.
Figur 1 illustrerer trinn 3 til 5.
Gratulerer! Du har nettopp laget din første pakke. Tenk på denne pakken som inneholder to klasser (EN
og B
) og EN
sitt eneste indre grensesnitt (Start stopp
). Du kan også tenke på denne pakken som en katalog som inneholder tre klassefiler: En $ StartStop.-klasse
, En klasse
, og B. klasse
.
Merk |
---|
For å minimere pakkenavnekonflikter (spesielt blant kommersielle pakker) har Sun etablert en konvensjon der selskapets Internett-domenenavn reverserer og prefikser et pakkenavn. For eksempel et selskap med x.com som internett-domenenavn og a.b som et pakkenavn (en ) etterfulgt av et underpakkenavn (b ) prefikser com.x til a.b , resulterer i com.x.a.b . Artikkelen min følger ikke denne konvensjonen fordi testpkg pakken er kun kastet designet for undervisningsformål. |
Importer klasser og grensesnitt for en pakke
Når du har en pakke, vil du importere klasser og / eller grensesnitt - faktisk navn på klasse og / eller grensesnitt - fra den pakken til programmet ditt, slik at det kan bruke disse klassene og / eller grensesnittene. En måte å utføre denne oppgaven på er å oppgi det fullstendige pakkenavnet (pakkenavnet og alle underpakkenavn) på hvert sted der referansetypenavnet (klassen eller grensesnittnavnet) vises, som oppføring 2 viser:
Oppføring 2. Usetestpkg1.java
// Usetestpkg1.java klasse Usetestpkg1 implementerer testpkg.A.StartStop {public static void main (String [] args) {testpkg.A a = new testpkg.A (); System.out.println (a.y); System.out.println (a.returny ()); Usetestpkg1 utp = ny Usetestpkg1 (); utp.start (); utp.stop (); } offentlig ugyldig start () {System.out.println ("Start"); } offentlig ugyldig stopp () {System.out.println ("Stopp"); }}
Ved å prefikse testpkg.
til EN
, Usetestpkg1
tilgang testpkg
sin klasse EN
to steder og EN
sitt indre grensesnitt Start stopp
på en plass. Fullfør følgende trinn for å kompilere og kjøre Usetestpkg1
:
- Åpne et Windows-kommandovindu og sørg for at du er i
c:
stasjonens rotkatalog. - Sørg for at
klassesti
miljøvariabel eksisterer ikke ved å utføreangi klassebane =
. (Jeg diskutererklassesti
senere i denne artikkelen.) - Bruk en redaktør til å angi kildekoden til Listing 2 og lagre den koden i en
Usetestpkg1.java
filen i rotkatalogen. - Kompilere
Usetestpkg1.java
ved å skrivejavac Usetestpkg1.java
. Du bør se klassefilenUsetestpkg1.klasse
vises i rotkatalogen. - Type
java Usetestpkg1
for å kjøre dette programmet.
Figur 2 illustrerer trinn 3 til 5 og viser programmets produksjon.
I følge Usetestpkg1
sin produksjon, den hoved()
metoden tråd har tilgang til testpkg.A
s y
felt og kaller retur ()
metode. Videre viser produksjonen en vellykket implementering av testpkg.A.StartStop
indre grensesnitt.
Til Usetestpkg1
, prefiks testpkg.
til EN
tre steder virker det ikke så veldig. Men hvem vil spesifisere et fullt kvalifisert pakkenavnsprefiks hundre steder? Heldigvis leverer Java import
direktivet om å importere pakkens offentlige referansetypenavn (er), slik at du ikke trenger å oppgi fullstendige prefiks for pakkenavn. Uttrykk en import
direktiv i kildekode via følgende syntaks:
'import' packageName [ '.' underpakkenavn ... ] '.' ( referansetypenavn | '*' ) ';'
An import
direktivet består av import
nøkkelord umiddelbart etterfulgt av en identifikator som navngir en pakke, packageName
. En valgfri liste over underpakkenavn
identifikatorer følger for å identifisere riktig underpakning (om nødvendig). Direktivet avsluttes med enten a referansetypenavn
identifikator som identifiserer en bestemt klasse eller et grensesnitt fra pakken, eller en stjerne (*
) karakter. Hvis referansetypenavn
vises, er direktivet en enkelttype import
direktivet. Hvis det vises en stjerne, er direktivet et type-on-demand import
direktivet.
Forsiktighet |
---|
Som med pakke direktiv, import direktiver må vises foran enhver annen kode, med tre unntak: a pakke direktiv, annet import direktiver, eller kommentarer. |
Den eneste typen import
direktiv importerer navnet på en enkelt offentlig referansetype fra en pakke, som følgende kodefragment viser:
importere java.util.Date;
Den forrige single-typen import
direktiv importerer klassenavn Dato
inn i kildekoden. Som et resultat spesifiserer du Dato
i stedet for java.util.Date
hvert sted vises kursnavnet i kildekoden. For eksempel når du oppretter en Dato
objekt, spesifiser Dato d = ny Dato ();
i stedet for java.util.Date d = ny java.util.Date ();
.
Utvis forsiktighet med en type import
direktiver. Hvis kompilatoren oppdager en enkelt type import
direktiv som spesifiserer et referansetypenavn som også er deklarert i en kildefil, rapporterer kompilatoren en feil, som følgende kodefragment viser:
importere java.util.Date; klasse Dato {}
Kompilatoren ser på kodefragmentet som et forsøk på å introdusere to referansetyper med det samme Dato
Navn: