Typiske Java-problemer
Udgave 1. Kommentarer og forslag til tilføjelser er velkomne.
Java-systemets fejlmeddelelser kan være ret vanskelige at forstå,
fordi systemet gætter forkert om hvad der er galt med dit program.
Denne liste over fejlmeddelelser og mulige årsager er ment som en
hjælp til opklaringen af hvad der faktisk er galt.
Husk at der faktisk er noget galt med dit program når
oversætteren brokker sig, og at det typisk er lige ved eller lige før
det sted oversætteren udpeger: kig meget kritisk på den del af dit
program! Læs fejlmeddelelsen omhyggeligt og se om ikke den giver et
vink om hvad der foregår. Logik er mere effektiv end panik.
Problemer ved oversættelse af Java-program (med Javac)
- Bad command or file name
- javac er ikke installeret
- Windows-variablen PATH er sat forkert
Prøv at skrive PATH i en DOS-boks; resultatet skal ligne dette:
path c:\windows;c:\windows\command;c:\jdk1.3\bin
- '}' expected.
-
Du har glemt en højre-krølleparentes i en metodeerklæring eller
til sidst i klassen
- Type expected.
-
Du har skrevet udtryk eller ordrer som ikke står inden for en
metode, konstruktor eller initialisator
- '{' expected.
- Du har glemt en venstre-krølleparentes efter metodens første linie
- Instance variables can't be void: main
- Du har glemt en parameterliste i parentes (...) i metode-hovedet
- '(' expected.
- Du har glemt en parameterliste i parentes (...) i metode-hovedet
- Identifier expected.
-
I en parameterliste: Der skal typenavn foran hver parameter i listen
- ')' expected.
-
I en parameterliste: Der skal typenavn foran hver parameter i listen
- Undefined variable: y
- Du har glemt at erklære en variabel eller parameter eller metode
eller felt, eller du har stavet det forkert. Det skal staves
præcis som det erklæres, og der skelnes mellem store og små
bogstaver, mellem cifret nul (0) og bogstavet o, osv.
- cannot resolve symbol
- Du har glemt at erklære en variabel eller parameter eller metode
eller felt, eller du har stavet det forkert. Det skal staves
præcis som det erklæres, og der skelnes mellem store og små
bogstaver, mellem cifret nul (0) og bogstavet o, osv.
- Incompatible type for declaration. Explicit cast needed to convert double to int.
- Du kan ikke gemme et flydendetals-resultat i en heltalsvariabel.
Hvis du virkelig vil, så benyt en typekonvertering (cast):
int x = (int)(3.14 * 12.4);
- possible loss of precision
- Du kan ikke gemme et flydendetals-resultat i en heltalsvariabel.
Hvis du virkelig vil, så benyt en typekonvertering (cast):
int x = (int)(3.14 * 12.4);
- Variable i may not have been initialized.
- Java-oversætteren tjekker at en variabel med sikkerhed er blevet
tildelt en værdi inden den bruges. Husk at felter (i klasser)
automatisk initialiseres, men at variable (i metoder) ikke
initialiseres. I nogle tilfælde kan oversætteren ikke se at en
variabel faktisk får en værdi, f.eks.:
int x;
for (int i=0; i<5; i++)
x = i;
System.out.println(x);
Eftersom for-løkkens krop faktisk udføres (5 gange), så får x
faktisk en værdi, men det ser oversætteren ikke. Initialiser
derfor variablen allerede i erklæringen: int x = 0; eller lign.
- Can't make a static reference to nonstatic variable x in class ...
- Du prøver at benytte en ikke-statisk variabel i en statisk
metode (eller fra en statisk initialisator). Det kan man ikke.
- non-static variable x cannot be referenced from a static context
- Du prøver at benytte en ikke-statisk variabel i en statisk
metode (eller fra en statisk initialisator). Det kan man ikke.
- Can't make static reference to method void foo(int) in class ...
- Du prøver at kalde en ikke-statisk metode fra en statisk metode
(eller fra en statisk initialisator).
- non-static method foo(int) cannot be referenced from a static
context
- Du prøver at kalde en ikke-statisk metode fra en statisk metode
(eller fra en statisk initialisator).
- Methods can't be overridden to be more private. Method java.lang.String toString() is public in class java.lang.Object.
- Metoden toString skal være public
- toString() in Mistake1 cannot override toString() in
java.lang.Object; attempting to assign weaker access priviliges; was public
- Metoden toString skal være public
- Method redefined with different return type: int toString() was
java.lang.String toString()
- Metoden toString skal have resultattype String.
- toString() in Mistake1 cannot override toString() in
java.lang.Object; attempting to use incompatible return type.
- Metoden toString skal have resultattype String.
- Class Random not found in type declaration.
- Class Vector not found in type declaration.
- Class Enumeration not found in type declaration.
- Du skal angive en import-erklæring
import java.util.*;
for at kunne benytte Random-klassen, Vector-klassen, eller
Enumeration-klassen (som er defineret i pakken java.util).
- cannot resolve symbol
symbol: class Random
- Du skal angive en import-erklæring
import java.util.*;
for at kunne benytte Random-klassen, Vector-klassen, eller
Enumeration-klassen (som er defineret i pakken java.util).
- Class DecimalFormat not found in type declaration.
- Du skal angive en import-erklæring
import java.text.*;
for at kunne benytte DecimalFormat-klassen (som er defineret i
pakken java.text).
- Class Button not found in type declaration.
- Class Label not found in type declaration.
- Class TextField not found in type declaration.
- Class Panel not found in type declaration.
- Du skal angive en import-erklæring
import java.awt.*;
for at kunne benytte Button-klassen og andre GUI-komponenter
(som er defineret i pakken java.awt).
- Class ActionListener not found in type declaration.
- Du skal angive en import-erklæring
import java.awt.event.*;
for at kunne benytte ActionListener-klassegrænsefladen
og andre lytter-komponenter (som er defineret i pakken java.awt.event).
- Class Applet not found in type declaration.
- Du skal angive en import-erklæring
import java.applet.*;
for at kunne benytte Applet-klassen (som er defineret i pakken
java.applet).
Problemer ved oversættelse af Java-program (med Jikes)
- Bad command or file name
- jikes er ikke installeret
- Windows-variablen PATH er sat forkert
Prøv at skrive PATH i en DOS-boks; resultatet skal ligne dette:
path c:\windows;c:\windows\command;c:\jdk1.3\bin
- *** Syntax Error: "}" inserted to complete ClassBody
- Du har glemt en højre-krølleparentes i en metodeerklæring eller
til sidst i klassen
- Du har skrevet udtryk eller ordrer som ikke står inden for en
metode, konstruktor eller initialisator
- *** Syntax Error: ; expected instead of this token
- Du har glemt en venstre-krølleparentes efter metodens første linie
- *** Syntax Error: ";" inserted to complete FieldDeclaration
- Du har glemt en parameterliste i parentes (...) i metode-hovedet
- *** Syntax Error: VariableDeclaratorId expected after this token
- i parameterliste: Der skal typenavn foran hver parameter i listen
- i klasseerklæring: Du har skrevet udtryk eller ordrer som ikke
står inden for en metode, konstruktor eller initialisator.
- *** Error: No entity named "y" was found in this environment.
- Du har glemt at erklære en variabel eller parameter eller metode
eller felt, eller du har stavet det forkert. Det skal staves
præcis som det erklæres, og der skelnes mellem store og små
bogstaver, mellem cifret nul (0) og bogstavet o, osv.
- *** Error: The type of the left-hand side in this assignment, "int",
is not compatible with the type of the right-hand side expression,
"double".
- Du kan ikke gemme et flydendetals-resultat i en heltalsvariabel.
Hvis du virkelig vil, så benyt en typekonvertering (cast):
int x = (int)(3.14 * 12.4);
- *** Error: The variable "i" may be accessed here before having been
definitely assigned a value.
- Java-oversætteren tjekker at en variabel med sikkerhed er blevet
tildelt en værdi inden den bruges. Husk at felter (i klasser)
automatisk initialiseres, men at variable (i metoder) ikke
initialiseres. I nogle tilfælde kan oversætteren ikke se at en
variabel faktisk får en værdi, f.eks.:
int x;
for (int i=0; i<5; i++)
x = i;
System.out.println(x);
Eftersom for-løkkens krop faktisk udføres (5 gange), så får x
faktisk en værdi, men det ser oversætteren ikke. Initialiser
derfor variablen allerede i erklæringen: int x = 0; eller lign.
- *** Error: The name "x" does not denote a class (static) variable.
- Du prøver at benytte en ikke-statisk variabel i en statisk
metode (eller fra en statisk initialisator). Det kan man ikke.
- *** Error: The method "foo" does not denote a class method.
- Du prøver at kalde en ikke-statisk metode fra en statisk metode
(eller fra en statisk initialisator).
- *** Error: The method "java.lang.String toString();" with default
access cannot override the method "java.lang.String toString();"
with public access declared in type "java/lang/Object".
- Metoden toString skal være public
- *** Error: The return type of method "int toString();" does not match
the return type of method "java.lang.String toString();" inherited
from type "java/lang/Object".
- Metoden toString skal have resultattype String.
- *** Error: Type Random was not found.
- *** Error: Type Vector was not found.
- *** Error: Type Enumeration was not found.
- Du skal angive en import-erklæring
import java.util.*;
for at kunne benytte Random-klassen, Vector-klassen, eller
Enumeration-klassen (som er defineret i pakken java.util).
- *** Error: Type DecimalFormat was not found.
- Du skal angive en import-erklæring
import java.text.*;
for at kunne benytte DecimalFormat-klassen (som er defineret i
pakken java.text).
- *** Error: Type Button was not found.
- *** Error: Type Label was not found.
- *** Error: Type TextField was not found.
- *** Error: Type Panel was not found.
- Du skal angive en import-erklæring
import java.awt.*;
for at kunne benytte Button-klassen og andre GUI-komponenter
(som er defineret i pakken java.awt).
- *** Error: Type ActionListener was not found.
- Du skal angive en import-erklæring
import java.awt.event.*;
for at kunne benytte ActionListener-klassegrænsefladen
og andre lytter-komponenter (som er defineret i pakken java.awt.event).
- *** Error: Type Applet was not found.
- Du skal angive en import-erklæring
import java.applet.*;
for at kunne benytte Applet-klassen (som er defineret i pakken
java.applet).
- *** Error: Type xyz was not found.
- Du skal angive en import-erklæring
import java.io.*;
for at kunne benytte Applet-klassen (som er defineret i pakken
java.applet).
Problemer ved kørsel af Java-program (med java)
- Bad command or file name
- Java er ikke installeret på maskinen; findes mappen C:\jdk1.3
overhovedet?
- Windows-variablen PATH er sat forkert
Prøv at skrive PATH i en DOS-boks; resultatet skal ligne dette:
path c:\windows;c:\windows\command;c:\jdk1.3\bin
- In class Mistake1: void main(String argv[]) is not defined
- Metoden main mangler eller har forkert argumenttype; den
skal være main(String[] args) eller main(String argv[]).
- In class Mistake2: main must be public and static
- Metoden main er ikke public eller ikke static; det skal den være
- Can't find class Myprog.class
- Programmet skal udføres med
java Myprog
ikke med java Myprog.class
- Can't find class Myprog.java
- Programmet skal udføres med
java Myprog
ikke med java Myprog.java
- Can't find class Myprog
-
Filen Myprog.class ligger et andet sted, f.eks. på H-drevet,
ikke C-drevet.
- Klassen hedder måske noget andet, f.eks. Myprogn, eller MyProg.
Den hedder nemlig eksakt -- med store og små bogstaver -- det der står
efter class i .java-filen, ikke det samme som .java-filen hedder.
- java.lang.ArrayIndexOutOfBoundsException: 0
at Myprog.main(Myprog.java:3)
- Programmet kræver kommandolinieargumenter, men du har ikke givet
nogen da du startede programmet:
java Myprog arg1 arg2 ...
- Dit program udfører en indeksering a[i] hvor i <
0 eller i >= a.length. Læg mærke til at
fejlmeddelelsen både angiver
den faktiske værdi af udtrykket i (til sidst på første
linie), og i hvilken programlinie fejlen opstod (til sidst på anden linie).
- obj.toString eller ("bla bla" + obj) giver mystisk resultat
i stil med Time@805e583
- Du har glemt at overskrive/redefinere metoden toString i klassen;
- Du har stavet metoden forkert, skal være toString;
- Du har erklæret metoden med forkert argumenttype, det skal være
toString()
- udregningen 45/90*100 skulle give 50, men giver 0
- Udtrykket udregnes fra venstre mod højre, altså (45/90)*100, og
heltalsdivision afrunder mod 0. Altså 45/90*100 er (45/90)*100 er
0*100 er 0.
Der er to udveje:
- Enten: gang med 100 først: 45*100/90
- Eller: brug flydendetals-division og nedrund til heltal bagefter:
(int)(45.0/90*100) eller (int)((double)45/90*100)
Problemer ved kørsel af applet (med appletviewer)
- Warning: No Applets were started. Make sure the input contains an <applet> tag.
- Man kan IKKE starte en applet MyApplet at skrive
appletviewer MyApplet
appletviewer MyApplet.java
appletviewer MyApplet.class
Man skal lave en HTML-fil MyApplet.html og starte appletten på denne måde:
appletviewer MyApplet.html
HTML-filen skal indeholde et APPLET-mærke (tag), se nedenfor.
- Warning: <applet> tag requires code attribute.
- Warning: <applet> tag requires height attribute.
- Warning: <applet> tag requires width attribute.
- HTML-filen der starter en applet skal have denne form:
<APPLET CODE="MyApplet.class" WIDTH=300 HEIGHT=300>
</APPLET>
Dvs der skal være et APPLET-mærke med attributterne CODE, WIDTH,
og HEIGHT.
- load: MyApplet.class is not public or has no public constructor.
- Din applet-klasse skal være public, altså
public class MyApplet extends Applet { ... }
- java.lang.ClassCastException: MyApplet
- Din applet-klasse skal være en subklasse af Applet, altså
public class MyApplet extends Applet { ... }
Peter Sestoft (sestoft@dina.kvl.dk) 2000-09-05