Java-kompilering

Fra TermvaktWiki
(Forskjell mellom revisjoner)
Gå til: navigasjon, søk
m
 
(31 mellomrevisjoner av 9 brukere vises ikke)
Linje 1: Linje 1:
== Kort innføring i Java-kompilering ==
+
Denne siden handler om programmeringsspråket Java. Ser du etter rommet med samme navn, se [[romnavn]].
  
 +
En kort innføring i Java-kompilering.
  
'''Anbefalte bakgrunnskunnskaper.'''
+
__TOC__
Denne veiledningen forutsetter at du kjenner til følgende:  
+
==Javainstallasjon på hjemmemaskin==
 +
Det er en egen artikkel som forklarer hvordan man kan [[installere java på hjemmemaskin]].
 +
 
 +
==Anbefalte bakgrunnskunnskaper.==
 +
Denne veiledningen forutsetter at du kjenner til følgende:
 
* Innlogging og vindusbehandling på en linuxmaskin
 
* Innlogging og vindusbehandling på en linuxmaskin
* Hva et terminalvindu er, og hvordan du angir en kommando i terminalvinduet.([[Bash]])
 
 
* Enkel filbehandling
 
* Enkel filbehandling
* Ett tekstredigeringsprogram i linux ([[Linux/emacs |Emacs]], [[Linux/vi]])  
+
* Et tekstredigeringsprogram ([[Emacs]], [[Vim]])  
  
===Om kompilering===
+
Det kan også være lurt å ha kjennskap til kommandobruk i enten Windows eller Linux (avhengig av hvilket operativsystem du bruker).
Kompilering er navet på prosessen som oversetter kildekode til maskinkode. Kildekode betegner formatet som vi skriver programmet i, men maskinkode er en sekvens av enere og nuller som datamaskinen forstår.
+
Denne veiledningen forklarer hvordan man kompilerer Java-, C- og C++-programmer. Den tar i tillegg for seg vannlige feilmeldinger ved kompilering og gir forslag på hvordan feilen kan løses.
+
Veiledningen er todelt. Del en tar for seg kompilering av javaprogrammer, mens del to tar for seg kompilering av C- og C++-programmer. Hver del er igjen delt opp i en enkel teoretisk og en praktisk del.
+
  
===Teori===
+
==Om kompilering==
Java er et programmeringsspråk som må kompileres, men hovedforskjellen fra tradisjonelle språk er at Java blir kompilert ned til bytecode. Denne bytecoden er plattformuavhengig. Det vil si at den kan kjøres både på Windos, Unix, Linux, Mac OS X, [=BeOS=] osv. ved hjelp av en bytecodetolker.
+
Kompilering er navnet på prosessen som oversetter kildekode til maskinkode. Kildekode betegner formatet som vi skriver programmet i, men maskinkode er en sekvens av enere og nuller som datamaskinen forstår.
 +
Denne veiledningen forklarer hvordan man kompilerer Java-programmer. Den tar i tillegg for seg vanlige feilmeldinger ved kompilering og gir forslag på hvordan feilene kan løses.
 +
 
 +
==Teori==
 +
Java er et programmeringsspråk som må kompileres, men hovedforskjellen fra tradisjonelle språk er at Java blir kompilert ned til en plattformuavhengig bytekode. Det vil si at den kan kjøres både på Windows, Unix, Linux, Mac OS X, BeOS osv. ved hjelp av en bytekodetolker som kan lese javas bytekode.
 
Under kan man se en figur over hvordan det ser ut.  
 
Under kan man se en figur over hvordan det ser ut.  
 
   
 
   
http://termvakt.uio.no/bilder/kompilering/Obj2.gif
+
[[Image:Obj2.gif]]
 
+
Man ser her at hver enkel prosessorarkitektur og/eller operativsystem har sin unike JVM. JVM står for Java Virtuel Machine. Det er denne maskinene som oversetter fra Java bytecode til nuller og ett-tall (0100101010100) som maskinene du sitter på skjønner.
+
 
+
===Kompilering og kjøring i praksis===
+
  
Det finnes to hovedkompilatorer for Java. Den ene er laget av Sun selv og heter javac og den andre heter jikes og er laget av IBM. Jeg kommer i denne veiledning til å bruke javac, siden det er den som blir brukt i kurs her [=UiO=]. Hovedforskjellen mellom disse to kompilatorene er at jikes har høyere ytelse og er Open Source. Her kan du lese mer om jikes.  http://oss.software.ibm.com/developerworks/opensource/jikes/
+
Man ser her at hver enkel prosessorarkitektur og/eller operativsystem har sin egen JVM (men en del arkitekturer og operativsystem har flere JVMer). JVM står for Java Virtual Machine. Det er denne maskinen som oversetter fra Java-bytekode til nuller og ett-tall (0100101010100) som maskinene du sitter skjønner.  
  
Så tilbake til Sun sin javac. Jeg skal nå vise et par eksempler på hvordan man kompilere små programmer i java og hvordan man kan finne kompileringsfeil. Vi bruker selvfølgelig det klassiske «Hello World!»-programmet.
+
==Kompilering og kjøring i praksis==
  
 +
En har ulike måter å kompilere Java-kode, men den vanligste er ved hjelp av programmet <tt>javac</tt> (det er mulig å kompilere Java direkte til bytekode ved gcj, men det går ut over denne veiledningen). Vi starter med følgende programsnutt:
  
 
  /**  
 
  /**  
   * The [=HelloWorldApp=] class implements an application that
+
   * The HelloWorldApp class implements an application that
 
   * simply displays "Hello World!" to the standard output.
 
   * simply displays "Hello World!" to the standard output.
 
   */
 
   */
  class [=HelloWorldApp=] {
+
  class HelloWorldApp {
 
     public static void main(String[] args) {
 
     public static void main(String[] args) {
 
         System.out.println("Hello World!"); //Display the string.
 
         System.out.println("Hello World!"); //Display the string.
Linje 39: Linje 41:
 
  }
 
  }
  
Vi skal nå kompilere hele dette programmet. Siden det er et javaprogram det er snakk om, navnet på fila ha samme navn som den klassen main() ligger i. Filen vi skal kompilere vil da hete [=HelloWorldApp.java=]. For å kompilere filen skriver du følgende kommando i et terminalvindu:
+
Vi skal nå kompilere hele dette programmet. Siden det er et javaprogram det er snakk om, skal helst navnet på fila ha samme navn som den klassen main() ligger i. Filen vi skal kompilere vil da hete HelloWorldApp.java (for enkelhet er det det lurt å lagre filen direkte på hjemmeområdet, hvis du sitter i Windows lagrer du da filen direkte under M:\-disken). For å kompilere filen, åpner du et terminalvindu eller kommandovindu, og beveger deg først til mappen filen ligger i (hvis du lagret filen på hjemmeområdet må du skrive <tt>M:</tt> i Windows, i Linux trenger du ikke å gjøre noe; hvis filen er lagret et annet sted, bruk kommando <tt>cd</tt> i Linux og <tt>chdir</tt> i Windows for å navigere mellom mapper). Deretter kjører du følgende kommando:
  
  isolde: ~-1>javac [=HelloWorldApp.java=]
+
  javac HelloWorldApp.java
isolde: ~-1>
+
  
Hvis kompileringen var feilfri(Dvs. at ingen feilmelding er kommet opp i terminalvinduet) så er det nå blitt laget en ny fil med navn [=HelloWorldApp.class=] Den nye filen inneholder bytecoden. For å kjøre programmet skriver du følgende inn i terminalvinduet:
+
Hvis kompileringen var feilfri (dvs. at ingen feilmelding er kommet opp i terminalvinduet), så er det nå blitt laget en ny fil med navn HelloWorldApp.class. Den nye filen inneholder bytecoden. For å kjøre programmet skriver du følgende inn i terminalvinduet:
  
  isolde: ~-1>java [=HelloWorldApp=]
+
  java HelloWorldApp
Hello World!
+
isolde: ~-1>
+
  
Som du ser er nå programmet blitt kjørt av JVM.
+
Hvis alt har gått bra, skal teksten "Hello World!" komme ut under linjen <tt>java HelloWorldApp</tt>.
  
===Kompileringsfeil===
+
==Kompileringsfeil==
  
I tillegg til at ”javac” programmet oversetter kildekoden til bytekode, så sjekker den at kildekoden er syntaktisk korrekt.(Syntaks er regler for hvordan en kan lage setninger el. deler av setninger på et gitt språk) Hvis kildekoden ikke er syntaktisk korrekt vil du få en melding om dette, samt at kompileringen vil stoppe opp. La oss legge inn en feil i [=HelloWorldApp.java=]-programmet og se hva som skjer når vi kompilerer.
+
I tillegg til at <tt>javac</tt>-programmet oversetter kildekoden til bytekode, så sjekker den at kildekoden er syntaktisk korrekt (syntaks er regler for hvordan en kan lage setninger el. deler av setninger på et gitt språk). Hvis kildekoden ikke er syntaktisk korrekt vil du få en melding om dette, samt at kompileringen vil stoppe opp. La oss legge inn en feil i HelloWorldApp.java-programmet og se hva som skjer når vi kompilerer.
  
 
  /**  
 
  /**  
   * The [=HelloWorldApp=] class implements an application that@]\\
+
   * The HelloWorldApp class implements an application that@]\\
 
   * simply displays "Hello World!" to the standard output.@]\\
 
   * simply displays "Hello World!" to the standard output.@]\\
 
   */
 
   */
  class [=HelloWorldApp=] {
+
  class HelloWorldApp {
 
     public static void main(String[] args) {
 
     public static void main(String[] args) {
 
         System.println("Hello World!"); //Display the string.
 
         System.println("Hello World!"); //Display the string.
Linje 68: Linje 67:
 
Vi skal nå se hva vår kompilator sier da:
 
Vi skal nå se hva vår kompilator sier da:
  
  isolde: ~-1> javac [=HelloWorldApp.java=]
+
  bruker@maskin: ~-1> javac HelloWorldApp.java
  [=HelloWorldApp.java:6:=] cannot resolve symbol
+
  HelloWorldApp.java:6: cannot resolve symbol
 
  symbol  : method println (java.lang.String)
 
  symbol  : method println (java.lang.String)
 
  location: class java.lang.System
 
  location: class java.lang.System
Linje 76: Linje 75:
 
  1 error
 
  1 error
  
Som vi ser sier kompilatoren i fra om at noe er galt. 6-tallet refererer til hvilken linje feilen befinner seg på. Dette er til stor hjelp når man feilsøker programmer. I større programmer eller programmer med veldig mange feil, er det ikke alltid kompilatoren klarer å gi så presise feilmeldinger.  
+
Som vi ser sier kompilatoren i fra om at noe er galt. 6-tallet refererer til hvilken linje feilen befinner seg på. Dette er til stor hjelp når man feilsøker programmer. I større programmer eller programmer med veldig mange feil, er det ikke alltid kompilatoren klarer å gi så presise feilmeldinger.  
  
Ubalanserte parenteser (eksempel {{}, {{, {{}{, osv er alle ubalanserte, fordi det ikke er like mange høyreparenteser som venstreparenteser.), samt manglende semikolon på slutten av en linje kan ofte være opphav til flere upresise og misvisende feilmeldinger.  Det er derfor en god regel og alltid sjekke dette når man ikke forstår en feil. (Tips: Bruk linjeskift og innrykk på en konsekvent måte som gjør det lett å se slike feil.)
+
Ubalanserte parenteser (eksempel {{}, {{, {{}{, osv. er alle ubalanserte, fordi det ikke er like mange høyreparenteser som venstreparenteser), samt manglende semikolon på slutten av en linje kan ofte være opphav til flere upresise og misvisende feilmeldinger.  Det er derfor en god regel å alltid sjekke dette når man ikke forstår en feil. (Tips: Bruk linjeskift og innrykk på en konsekvent måte som gjør det lett å se slike feil.)
  
===Kjøretidsfeil===
+
==Kjøretidsfeil==
  
Selv om du får kompilert, kan programmet fortsatt inneholde en god del feil som først oppdages ved kjøring. (Dvs. når du gir kommandoen ”java [=HelloWorldApp=]”). Disse feilene er ofte mindre informative og dermed vanskeligere å tolke en kompileringsfeil. Vi tar en titt på noen av de vanligste kjøretidsfeilene. La oss ta utgangspunkt i følgende program:
+
Selv om du får kompilert, kan programmet fortsatt inneholde en god del feil som først oppdages ved kjøring. (Dvs. når du gir kommandoen ”java HelloWorldApp”). Disse feilene er ofte mindre informative og dermed vanskeligere å tolke en kompileringsfeil. Vi tar en titt på noen av de vanligste kjøretidsfeilene. La oss ta utgangspunkt i følgende program:
  
   1: /* The [=HelloWorldApp=] class implements an application that
+
   1: /* The HelloWorldApp class implements an application that
 
   2:  simply displays "Hello World!" to the standard output.
 
   2:  simply displays "Hello World!" to the standard output.
 
   3:  */
 
   3:  */
   4: class [=HelloWorldApp=] {
+
   4: class HelloWorldApp {
 
   5:    public static void main(String[] args) {
 
   5:    public static void main(String[] args) {
 
   6:
 
   6:
Linje 102: Linje 101:
 
  17:        System.out.println(ord[1].length());
 
  17:        System.out.println(ord[1].length());
 
  18:   
 
  18:   
  19:        // Print the ord array
+
  19:        // Print the word array
 
  20:        for(; i < 4; i++){
 
  20:        for(; i < 4; i++){
 
  21:            System.out.println(ord[i]); //Display the string.
 
  21:            System.out.println(ord[i]); //Display the string.
Linje 113: Linje 112:
 
Programmet kompilerer og kjører uten problemer i sin nåværende form:  
 
Programmet kompilerer og kjører uten problemer i sin nåværende form:  
  
  isolde: ~-1> javac [=HelloWorldApp.java=]
+
  javac HelloWorldApp.java
  isolde: ~-1> java [=HelloWorldApp=]
+
  java HelloWorldApp
 +
 
 +
Output:
 
  5
 
  5
 
  Hello
 
  Hello
Linje 120: Linje 121:
 
  !
 
  !
 
  null
 
  null
  isolde: ~-1>
+
  bruker@maskin: ~-1>
  
 
La oss så fremprovosere noen kjøretidsfeil:
 
La oss så fremprovosere noen kjøretidsfeil:
  
====ArrayIndexOutOfBoundsException====
+
==ArrayIndexOutOfBoundsException==
 
Ved å endre linje 15 til ”for(;i < 5;i++)” får vi følgende feil:
 
Ved å endre linje 15 til ”for(;i < 5;i++)” får vi følgende feil:
  
  isolde: ~-1> javac [=HelloWorldApp.java=]
+
  bruker@maskin: ~-1> javac HelloWorldApp.java
  isolde: ~-1> java [=HelloWorldApp=]
+
  bruker@maskin: ~-1> java HelloWorldApp
 
  5
 
  5
 
  Hello
 
  Hello
Linje 134: Linje 135:
 
  !
 
  !
 
  null
 
  null
  Exception in thread "main" [=java.lang.ArrayIndexOutOfBoundsException: 4=]
+
  Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
         at [=HelloWorldApp.main(HelloWorldApp.java:21)=]
+
         at HelloWorldApp.main(HelloWorldApp.java:21)
 
  isolde: ~-1>
 
  isolde: ~-1>
  
Linje 141: Linje 142:
 
Indeksen er enten negativ eller større eller lik størrelsen av arrayen. Tallet 4  
 
Indeksen er enten negativ eller større eller lik størrelsen av arrayen. Tallet 4  
 
i feilmeldingen angir den ugyldige indeksverdien og tallet 21 angir hvilken linje  
 
i feilmeldingen angir den ugyldige indeksverdien og tallet 21 angir hvilken linje  
i [=HelloWorldApp.java=] som fremprovoserte feilen. Vi vet altså at det var  
+
i HelloWorldApp.java som fremprovoserte feilen. Vi vet altså at det var  
 
”System.out.println(ord[4]);” som er kilden til feilen, og det er ikke så vanskelig  
 
”System.out.println(ord[4]);” som er kilden til feilen, og det er ikke så vanskelig  
 
å forstå at ord[4] refererer til en plassering i arrayen som ikke finnes. Arrayen  
 
å forstå at ord[4] refererer til en plassering i arrayen som ikke finnes. Arrayen  
Linje 148: Linje 149:
 
egentlig refererer til element 5 siden tellingen av elementer i arrayen starter med 0.)
 
egentlig refererer til element 5 siden tellingen av elementer i arrayen starter med 0.)
  
 
+
==NullPointerException==
====NullPointerException====
+
 
Ved å endre linje 17  til ”System.out.println(ord[3].length());” får vi følgende feil:
 
Ved å endre linje 17  til ”System.out.println(ord[3].length());” får vi følgende feil:
  
  isolde: ~-1> javac [=HelloWorldApp.java=]
+
  bruker@maskin: ~-1> javac HelloWorldApp.java
  isolde: ~-1>  java [=HelloWorldApp=]
+
  bruker@maskin: ~-1>  java HelloWorldApp
  Exception in thread "main" [=java.lang.NullPointerException=]
+
  Exception in thread "main" java.lang.NullPointerException
         at [=HelloWorldApp.main(HelloWorldApp.java:17)=]
+
         at HelloWorldApp.main(HelloWorldApp.java:17)
  isolde: ~-1>
+
  bruker@maskin: ~-1>
  
 
Feilen angir at det er gjort et forsøk på å bruke ”null” i et tilfelle hvor  
 
Feilen angir at det er gjort et forsøk på å bruke ”null” i et tilfelle hvor  
Linje 191: Linje 191:
 
mange sider boken som er registrert på kartotekkort nr 3 har. Når så bibliotekaren  
 
mange sider boken som er registrert på kartotekkort nr 3 har. Når så bibliotekaren  
 
henter kort nr 3 finner han ut at kortet er blankt og må dessverre si at boken
 
henter kort nr 3 finner han ut at kortet er blankt og må dessverre si at boken
mangler.([=NullPointerException=]) Så tilbake til PC terminologien. Linje 17 gir  
+
mangler.(NullPointerException) Så tilbake til PC terminologien. Linje 17 gir  
 
beskjed at datamaskinen skal lese adressen registrert i arrayens plass 3 og  
 
beskjed at datamaskinen skal lese adressen registrert i arrayens plass 3 og  
 
deretter gå til denne adressen, hente ut hvor lang teksten var, men som vi husker
 
deretter gå til denne adressen, hente ut hvor lang teksten var, men som vi husker
 
er det ikke blitt registrert noen adresse i plass 3. Det er altså på grunn av at
 
er det ikke blitt registrert noen adresse i plass 3. Det er altså på grunn av at
 
det ikke eksisterer en peker i plass 3 til et objekt at vi får feilen  
 
det ikke eksisterer en peker i plass 3 til et objekt at vi får feilen  
[=NullPointerException.=] Løsningen kunne for eksempel ha vært å legge til følgende  
+
NullPointerException. Løsningen kunne for eksempel ha vært å legge til følgende  
 
linje rett etter linje 13:
 
linje rett etter linje 13:
 +
 +
ord[3] = new String("Nå er alt i orden");
 +
 +
==Ekstern informasjon==
 +
[http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html Hjemmesiden til Sun sin javac kompilator]
 +
 +
[http://www.howstuffworks.com/program.htm Hvordan java programmering fungerer]
 +
 +
[http://amath.colorado.edu/computing/software/man/java.html Man side for java]
 +
 +
[http://amath.colorado.edu/computing/software/man/javac.html Man side for javac]
  
 +
[http://www.manpagez.com/man/1/jikes/ Man side for jikes]
  
ord[3] = new String("Nå er alt i orden");
+
[[Category:Programmering]]
 +
[[Kategori:Windows]]
 +
[[Kategori:Linux]]

Nåværende revisjon fra 24. feb 2016 kl. 07:58

Denne siden handler om programmeringsspråket Java. Ser du etter rommet med samme navn, se romnavn.

En kort innføring i Java-kompilering.

Innhold

Javainstallasjon på hjemmemaskin

Det er en egen artikkel som forklarer hvordan man kan installere java på hjemmemaskin.

Anbefalte bakgrunnskunnskaper.

Denne veiledningen forutsetter at du kjenner til følgende:

  • Innlogging og vindusbehandling på en linuxmaskin
  • Enkel filbehandling
  • Et tekstredigeringsprogram (Emacs, Vim)

Det kan også være lurt å ha kjennskap til kommandobruk i enten Windows eller Linux (avhengig av hvilket operativsystem du bruker).

Om kompilering

Kompilering er navnet på prosessen som oversetter kildekode til maskinkode. Kildekode betegner formatet som vi skriver programmet i, men maskinkode er en sekvens av enere og nuller som datamaskinen forstår. Denne veiledningen forklarer hvordan man kompilerer Java-programmer. Den tar i tillegg for seg vanlige feilmeldinger ved kompilering og gir forslag på hvordan feilene kan løses.

Teori

Java er et programmeringsspråk som må kompileres, men hovedforskjellen fra tradisjonelle språk er at Java blir kompilert ned til en plattformuavhengig bytekode. Det vil si at den kan kjøres både på Windows, Unix, Linux, Mac OS X, BeOS osv. ved hjelp av en bytekodetolker som kan lese javas bytekode. Under kan man se en figur over hvordan det ser ut.

Obj2.gif

Man ser her at hver enkel prosessorarkitektur og/eller operativsystem har sin egen JVM (men en del arkitekturer og operativsystem har flere JVMer). JVM står for Java Virtual Machine. Det er denne maskinen som oversetter fra Java-bytekode til nuller og ett-tall (0100101010100) som maskinene du sitter på skjønner.

Kompilering og kjøring i praksis

En har ulike måter å kompilere Java-kode, men den vanligste er ved hjelp av programmet javac (det er mulig å kompilere Java direkte til bytekode ved gcj, men det går ut over denne veiledningen). Vi starter med følgende programsnutt:

/** 
 * The HelloWorldApp class implements an application that
 * simply displays "Hello World!" to the standard output.
 */
class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!"); //Display the string.
    }
}

Vi skal nå kompilere hele dette programmet. Siden det er et javaprogram det er snakk om, skal helst navnet på fila ha samme navn som den klassen main() ligger i. Filen vi skal kompilere vil da hete HelloWorldApp.java (for enkelhet er det det lurt å lagre filen direkte på hjemmeområdet, hvis du sitter i Windows lagrer du da filen direkte under M:\-disken). For å kompilere filen, åpner du et terminalvindu eller kommandovindu, og beveger deg først til mappen filen ligger i (hvis du lagret filen på hjemmeområdet må du skrive M: i Windows, i Linux trenger du ikke å gjøre noe; hvis filen er lagret et annet sted, bruk kommando cd i Linux og chdir i Windows for å navigere mellom mapper). Deretter kjører du følgende kommando:

javac HelloWorldApp.java

Hvis kompileringen var feilfri (dvs. at ingen feilmelding er kommet opp i terminalvinduet), så er det nå blitt laget en ny fil med navn HelloWorldApp.class. Den nye filen inneholder bytecoden. For å kjøre programmet skriver du følgende inn i terminalvinduet:

java HelloWorldApp

Hvis alt har gått bra, skal teksten "Hello World!" komme ut under linjen java HelloWorldApp.

Kompileringsfeil

I tillegg til at javac-programmet oversetter kildekoden til bytekode, så sjekker den at kildekoden er syntaktisk korrekt (syntaks er regler for hvordan en kan lage setninger el. deler av setninger på et gitt språk). Hvis kildekoden ikke er syntaktisk korrekt vil du få en melding om dette, samt at kompileringen vil stoppe opp. La oss legge inn en feil i HelloWorldApp.java-programmet og se hva som skjer når vi kompilerer.

/** 
 * The HelloWorldApp class implements an application that@]\\
 * simply displays "Hello World!" to the standard output.@]\\
 */
class HelloWorldApp {
    public static void main(String[] args) {
        System.println("Hello World!"); //Display the string.
    }   //    +- Her mangler out.
}

Vi skal nå se hva vår kompilator sier da:

bruker@maskin: ~-1> javac HelloWorldApp.java
HelloWorldApp.java:6: cannot resolve symbol
symbol  : method println (java.lang.String)
location: class java.lang.System
    System.println("Hello World!"); //Display the string.
          ^
1 error

Som vi ser sier kompilatoren i fra om at noe er galt. 6-tallet refererer til hvilken linje feilen befinner seg på. Dette er til stor hjelp når man feilsøker programmer. I større programmer eller programmer med veldig mange feil, er det ikke alltid kompilatoren klarer å gi så presise feilmeldinger.

Ubalanserte parenteser (eksempel {{}, {{, {{}{, osv. er alle ubalanserte, fordi det ikke er like mange høyreparenteser som venstreparenteser), samt manglende semikolon på slutten av en linje kan ofte være opphav til flere upresise og misvisende feilmeldinger. Det er derfor en god regel å alltid sjekke dette når man ikke forstår en feil. (Tips: Bruk linjeskift og innrykk på en konsekvent måte som gjør det lett å se slike feil.)

Kjøretidsfeil

Selv om du får kompilert, kan programmet fortsatt inneholde en god del feil som først oppdages ved kjøring. (Dvs. når du gir kommandoen ”java HelloWorldApp”). Disse feilene er ofte mindre informative og dermed vanskeligere å tolke en kompileringsfeil. Vi tar en titt på noen av de vanligste kjøretidsfeilene. La oss ta utgangspunkt i følgende program:

 1: /* The HelloWorldApp class implements an application that
 2:  simply displays "Hello World!" to the standard output.
 3:  */
 4: class HelloWorldApp {
 5:     public static void main(String[] args) {
 6:
 7:         int i = 0;
 8:         String ord[] = new String[4];
 9:
10:         // Fill array with information
11:         ord[0] = new String("Hello ");
12:         ord[1] = new String("World");
13:         ord[2] = "!"; // This is just a shorthand notation 
14:                       // for 'new String "!"; '
15:
16:         // Print the number of characters in ord[1]
17:         System.out.println(ord[1].length());
18:  
19:         // Print the word array
20:         for(; i < 4; i++){
21:             System.out.println(ord[i]); //Display the string.
22:         }
23:     }
24: }


Programmet kompilerer og kjører uten problemer i sin nåværende form:

javac HelloWorldApp.java
java HelloWorldApp

Output:

5
Hello
World
!
null
bruker@maskin: ~-1>

La oss så fremprovosere noen kjøretidsfeil:

ArrayIndexOutOfBoundsException

Ved å endre linje 15 til ”for(;i < 5;i++)” får vi følgende feil:

bruker@maskin: ~-1> javac HelloWorldApp.java
bruker@maskin: ~-1> java HelloWorldApp
5
Hello
World
!
null
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
        at HelloWorldApp.main(HelloWorldApp.java:21)
isolde: ~-1>

Feilen angir at en det er blitt referert til en array med en ugyldig indeksverdi. Indeksen er enten negativ eller større eller lik størrelsen av arrayen. Tallet 4 i feilmeldingen angir den ugyldige indeksverdien og tallet 21 angir hvilken linje i HelloWorldApp.java som fremprovoserte feilen. Vi vet altså at det var ”System.out.println(ord[4]);” som er kilden til feilen, og det er ikke så vanskelig å forstå at ord[4] refererer til en plassering i arrayen som ikke finnes. Arrayen ble via linje 8 gitt en størrelse på 4 elementer, som tilsvarer at ord[0], ord[1], ord[2] og ord[3] er gyldige referanser.(NB! Det er lett å glemme/overse at 4 egentlig refererer til element 5 siden tellingen av elementer i arrayen starter med 0.)

NullPointerException

Ved å endre linje 17 til ”System.out.println(ord[3].length());” får vi følgende feil:

bruker@maskin: ~-1> javac HelloWorldApp.java
bruker@maskin: ~-1>  java HelloWorldApp
Exception in thread "main" java.lang.NullPointerException
        at HelloWorldApp.main(HelloWorldApp.java:17)
bruker@maskin: ~-1>

Feilen angir at det er gjort et forsøk på å bruke ”null” i et tilfelle hvor et objekt var påkrevd. Tallet 17 angir hvilken linje som fremprovoserte feilen. For å forstå denne feilen er det nødvendig å forstå pekere og objekter.

Linje 8 medfører at det blir laget en array med plass til 4 pekere. Det er altså ikke meningen at arrayen skal inneholde selve teksten, noe som enn lett kan tro at skulle være tilfellet ved å se på linjene 11-13. Hvis ikke selve arrayen inneholder tekstene, hva er det da som skjer, hvor blir tekstene av?

Arrayen kan sammenlignes med et kartotek for et bibliotek. Når biblioteket mottar en tekst/bok så legges ikke selve boken inn i kartoteket, men de finner en ledig hylleplass og noterer hyllenummer og seksjon der boken blir plassert på et kartotekkort, og så legges kortet i kartoteket.

Litt forenklet kan vi si at det er det samme som skjer i en PC. Linje 8 medfører i bibliotekverdenen at det opprettes et kartotek med fire blanke kartotekkort. Linjene 11-13 tilsvarer 3 bokleveranser til biblioteket. Når bøkene er registrert og plassert er 3 av de fire kortene i kartoteket fylt ut med plasseringsinformasjon.

Hvis vi trekker samme historie inn i PC-terminologi så skjer følgende: Linje 8 setter av 8 minneplasser hvor hver plass har mulighet for å lagre en adresse til en annen plassering i minne(en peker). Når vi utfører linjen 11 søker vi etter en ledig plass i minne til teksten ”Hello”. (et tekstobjekt.). Når så en stor nok ledig plass er funnet, noteres startadressen til denne ledige plassen i arrayplassen angitt av indeksen [i]. I linje 11 ser vi at startadressen skal lagres i arrayplassen 0. Tilsvarende ting skjer for linje 12 og 13. Når disse linjene er ferdig utført inneholder plassene 0, 1, 2 startadresseinformasjon til henholdsvis tekstene; ”Hello”, ”World” og ”!”. Den siste plassen (3) inneholder fortsatt ingen referanse til et objekt.

Det som mangler nå er å forstå hvorfor linje 17 feiler. I bibliotekverdenen tilsvarer linje 17 at en person kommer inn i biblioteket, og spør etter hvor mange sider boken som er registrert på kartotekkort nr 3 har. Når så bibliotekaren henter kort nr 3 finner han ut at kortet er blankt og må dessverre si at boken mangler.(NullPointerException) Så tilbake til PC terminologien. Linje 17 gir beskjed at datamaskinen skal lese adressen registrert i arrayens plass 3 og deretter gå til denne adressen, hente ut hvor lang teksten var, men som vi husker er det ikke blitt registrert noen adresse i plass 3. Det er altså på grunn av at det ikke eksisterer en peker i plass 3 til et objekt at vi får feilen NullPointerException. Løsningen kunne for eksempel ha vært å legge til følgende linje rett etter linje 13:

ord[3] = new String("Nå er alt i orden");

Ekstern informasjon

Hjemmesiden til Sun sin javac kompilator

Hvordan java programmering fungerer

Man side for java

Man side for javac

Man side for jikes

Personlige verktøy
Navnerom
Varianter
Handlinger
Navigasjon
Kategorier
Programvare
Andre
Translate
Verktøy