Indhold:
Forstå pakkebegrebet og nøgleordet import
Importere og bruge standardpakkerne
Definere egne pakker
Kapitlet forudsættes ikke i resten af bogen, men er ofte en fordel, når man skal programmere i praksis.
Forudsætter kapitel 4, Definition af klasser.
Når man laver større programmer (over 30-40 klasser), kan det være nyttigt at opdele dem i grupper. En pakke er en samling af klasser, der på en eller anden måde er beslægtede.
En pakke er en navngiven samling af klasser
Javas standardbibliotek på mere end 1000 klasser er delt op i ca. 30 mindre pakker.
Pakker svarer til (klasse)biblioteker i C eller C++ eller "unit"-begrebet i PASCAL.
Vi har set, at når vi skal benytte klasser, der ligger ud over de helt grundlæggende, bliver vi nødt til at meddele compileren, hvor den kan forvente at finde definitionen af klassen. Dette kaldes at importere klassen.
Egentlig kunne vi godt helt udelade import-sætninger og skrive det fulde pakke- og klassenavn hver gang. Hvis vi f.eks. vil benytte ArrayList-klassen, kunne vi skrive:
java.util.ArrayList l;
l = new java.util.ArrayList();
Det er jo lidt besværligt og derfor kan vi vælge øverst i kildetekstfilen at skrive:
import java.util.ArrayList;
Dette får compileren til at lede i java.util-pakken, hvis den møder en klasse, den ikke umiddelbart genkender. Nu kan vi skrive, som vi plejer:
ArrayList l;
l = new ArrayList();
Der kan forekomme et hvilket som helst antal import-sætninger i en javafil. Import-sætninger skal stå først i filen, før klassedefinitionen. Hvis man ønsker at importere flere klassedefinitioner fra samme pakke, kan man skrive en * i stedet for klassenavnet:
import java.util.*;
Dermed importerer man samtlige klasser fra denne pakke. Det vil sige, at compileren leder denne pakke igennem, når den møder en klasse, den ikke umiddelbart genkender. De klassedefinitioner, der ikke bruges, bliver altså bare ignoreret.
Import af en klasse gør blot definitionen af klassen kendt for compileren – det gør ikke det færdige program større eller langsommere
I Javas indbyggede hjælpesystem kan man se de forskellige indbyggede pakker, der indeholder en række nyttige klasser. De vigtigste standardpakker er:
java.lang grundfunktioner i sproget
java.util nyttige værktøjer, såsom Date, ArrayList og meget andet
java.awt Abstract Window Toolkit. Grafikprogrammering (se kapitel 9 og 11)
java.io IO-funktioner, filhåndtering og datastrømme (se kapitel 15)
java.net netværksfaciliteter (se kapitel 16)
java.rmi Remote Method Invocation – til distribuerede systemer (se kapitel 19)
java.sql databaseadgang (også kaldet JDBC, se kapitel 20)
java.text håndtering af tekst uafhængigt af sprog
javax.swing avanceret vinduesbaseret programmering (se avanceret-afsnit i kapitel 11)
Hvorfor hedder den sidste javax? javax betød oprindeligt, at det var en udvidelse til sproget, som ikke var en del af det egentlige standardbibliotek og som måske aldrig bliver det. Efterhånden er en del javax-pakker (som javax.swing) dog alligevel kommet med.
Et andet eksempel er javax.comm, som er en kommunikationspakke, der håndterer seriel og parallel transmission af data. Denne pakke er ikke kommet med i standardbiblioteket.
De mest basale javaklasser, eksempelvis String, ligger i pakken java.lang. Denne særlige pakke indeholder en masse grundfunktioner og importeres altid af compileren. Det er altså ikke nødvendigt at importere den eksplicit med import java.lang.*;
Af andre klasser i java.lang kan nævnes System (til f.eks. System.out.println()) og Math (til f.eks. Math.random() og Math.sqrt()).
Hvis vi husker, at en pakke er en navngiven samling af klasser, er det nærliggende at tænke på, hvordan filer er organiseret i undermapper på et filsystem.
En klasse svarer til en fil på filsystemet
En pakke svarer til en undermappe på filsystemet
For eksempel findes klassen java.util.ArrayList som filen ArrayList.class i en mappe, der hedder util, som er en undermappe til en mappe, der hedder java: java/util/ArrayList.class (i Windows: java\util\ArrayList.class).
Ofte er .class-filerne og mapperne pakket i et såkaldt Java-arkiv (.jar-fil). jar-filer minder meget om zip-filer.
Compileren skal kende pakkens fysiske placering i filsystemet:
Som en undermappe med samme navn som pakken.
I en undermappe med samme navn som pakken et andet sted i filsystemet, som der henvises til med CLASSPATH-variablen.
I en jar-fil, som der henvises til med CLASSPATH-variablen.
CLASSPATH-variablen er en miljøvariabel, der minder om PATH-variablen (defineret i AUTOEXEC.BAT i DOS). Den angiver de steder, hvor compileren skal lede efter klassedefinitioner.
Man kan definere sine egne pakker. Dette er specielt brugbart i større systemer, hvor man har mange klasser med beslægtede funktioner, for eksempel kommunikation (internetkøb med VISA eller Dankort) eller sine egne matematik- eller datobearbejdningspakker.
Det er normalt at man benytter sin internetadresse eller firmanavn i navngivningen af pakkerne. F.eks: oracle.jdeveloper.layout.XYLayout (klassen er XYLayout og pakken er oracle.jdeveloper.layout), com.sybase.jdbc.SybDriver eller netscape.javascript.JSObject.
I følgende eksempel findes to klasser, nemlig Klasse1 og Klasse2 i en pakke (der hedder minPakke). De bruges af den eksekverbare main()-klasse BenytPakker:
import minPakke.*;
public class BenytPakker
{
public static void main(String[] arg)
{
Klasse1 a = new Klasse1();
Klasse2 b = new Klasse2();
a.snak();
b.snak();
}
}
Klasse1 og Klasse2 skal ligge i en undermappe, der hedder minPakke:
// Filnavn: minPakke/Klasse1.java
package minPakke;
public class Klasse1
{
public void snak()
{
System.out.println("Dette er Klasse1, der taler!");
}
}
// Filnavn: minPakke/Klasse2.java
package minPakke;
public class Klasse2
{
public void snak()
{
System.out.println("Dette er Klasse2, der taler!");
}
}
Laver man sine egne pakker, ønsker man ofte at kunne distribuere de oversatte .class-filer med bytekoden til andre. Det gøres nemmest ved at pakke filerne i en jar-fil.
En jar-fil skabes med et zip-værktøj som WinZip eller GnoZip til Linux eller fra kommandolinjen med kommandoen jar, der følger med, når man installerer Java. Den minder meget om UNIX' tar-kommando. Man opretter et arkiv ved at skrive f.eks.:
jar cf program.jar *.class minPakke
Dette vil oprette jar-filen program.jar med alle class-filer i mappen (herunder BenytPakker.class) og alle filerne i undermappen minPakke (d.v.s. minPakke/Klasse1.class og minPakke/Klasse2.class).
Derefter kan main()-metoden i BenytPakker udføres ved at blot skrive
java -cp program.jar BenytPakker
Hvis man vil distribuere sit program til mange mennesker, kan det være bekvemt, at brugerne kan dobbeltklikke på jar-filen, lige som f.eks. Windows-brugere dobbeltklikker på .exe-filer. Det kræver, at man lægger en såkaldt manifest-fil med ned i jar-filen:
jar cfm program.jar manifestfil.txt *.class minPakke
Filen manifestfil.txt angiver klassen med main()-metoden:
Manifest-Version: 1.0
Main-Class: BenytPakker
Der er et par irriterende småting der kan give problemer, herunder fil- og mappeplacering og at manifestfilen skal afslutte med et linjeskift. Mange bruger derfor deres udviklingsværktøj til at lave jar-filen (JBuilder: File|New|Archive|Application) eller ændrer en eksisterende jar-fil med WinZip eller et andet værktøj der kan rette i ZIP-filer.
Til sidst kan man køre BenytPakker ved at at dobbeltklikke på program.jar (hvis filassociationerne er sat korrekt op). Ellers kan man fra kommandolinjen starte programmet med:
java -jar program.jar
Søg i din computer efter filer, der
ender på .jar og åbn dem med et program, der kan læse
ZIP-komprimerede filer (f.eks unzip eller WinZip).
Hvordan er
filerne organiseret?
Se, om du kan finde filen, der indeholder
ArrayList-klassen.
I hvilken undermappe ligger den?
Opret nogle klasser i en pakke og en
main()-klasse, der benytter dem
(f.eks. BenytPakker.java,
minPakke/Klasse1.java og minPakke/Klasse2.java).
Pak dem i en jar-fil.
Prøv at oprette en eksekverbar jar-fil. Prøv derefter at køre den.
Til de sidste tre opgaver kan det være en fordel at gå ind på den elektroniske udgave af bogen, http://javabog.dk og kopiere teksten i stedet for at taste den ind.