/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
NullPointerException, forklaring søges
Fra : Janus


Dato : 17-09-05 12:19

Hej NG!

Her er en snip kode:


private void tsbAddButtonPressedAction() {
   AddTSB addTSB = new AddTSB(frame) {
      public void abstractCancelButtonPressed() {
         closeWindow();
      }
      public void abstractOkButtonPressed(TSB tsb) {
         System.out.println("TSB returned: "+ tsb);
         addTSB(tsb);
         updateTSBTable();
         closeWindow();
      }
   };
}
   
private void addTSB(TSB tsb) {
   mAnalysis.addTSB(tsb);
}



Mit problem er så, at får en NullPointerException, når funktionen AddTSB
kaldes (Ecplise 3.0.1, java 1.5.0_04):

Exception occurred during event dispatching:
java.lang.NullPointerException
   at gui.AddTSA.access$10(AddTSA.java:283)

Stacktracet er selvfølgelig længere end dette.

Linie 283 er: private void addTSB(TSB tsb) {


tsb'en bliver printet som det skal i System.out.println'en, men hvorfor
kan denne objektreference ikke nå til addTSB()? Jeg genererer
TSB-objektet i AddTSB gennem abstractOkButtonPressed(createDataSet()),
dvs. som "anonymt" (createDataSet returnerer objektet TSB), og det er
dette der er problemet! Hvis jeg i createDataSet() også binder en
reference til en private TSB tbs og bruger denne objektreference som
parameter til abstractOkButtonPressed(), virker det hele.

Men jeg har godt nok svært ved at se forskellen på disse to
fremgangsmåder, da begge dele foregår indefor samme klasse, og dermed
vel ikke har/burde have nogen indflydelse på object-scope i min
konkretisering af den abstrakte metode abstractOkButtonPressed?



Med venlig hilsen Janus


 
 
Thorbjoern Ravn Ande~ (17-09-2005)
Kommentar
Fra : Thorbjoern Ravn Ande~


Dato : 17-09-05 18:00

Janus <nospam@nomail.com> writes:

> Mit problem er så, at får en NullPointerException, når funktionen
> AddTSB kaldes (Ecplise 3.0.1, java 1.5.0_04):

Prøv at klikke på NullPointerException i dit staktrace i COnsolen og
derved aktivere et exception-breakpoint. Kør igen i Debug mode.

Programmet stopper nu der hvor fejlen sker, og du kan se hvad
variablene er på de forskellige niveauer ved at klikke på den
pågældende linie i debug-viewet.

Mit bud er at mAnalysis ikke er initialiseret.

--
Thorbjørn Ravn Andersen
http://unixsnedkeren.dk/ravn/

Janus (18-09-2005)
Kommentar
Fra : Janus


Dato : 18-09-05 02:10

Thorbjoern Ravn Andersen wrote:
> Janus <nospam@nomail.com> writes:
>
>
>>Mit problem er så, at får en NullPointerException, når funktionen
>>AddTSB kaldes (Ecplise 3.0.1, java 1.5.0_04):
>
>
> Prøv at klikke på NullPointerException i dit staktrace i COnsolen og
> derved aktivere et exception-breakpoint. Kør igen i Debug mode.
>
> Programmet stopper nu der hvor fejlen sker, og du kan se hvad
> variablene er på de forskellige niveauer ved at klikke på den
> pågældende linie i debug-viewet.
>
> Mit bud er at mAnalysis ikke er initialiseret.
>

mAnalysis eksisterer. Alle variable og objekter er initaliseret, ingen
nullpointers nogle steder.

Se evt svar på andet svar.

Vh Janus

--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Thorbjoern Ravn Ande~ (18-09-2005)
Kommentar
Fra : Thorbjoern Ravn Ande~


Dato : 18-09-05 07:21

Janus <nospam@nomail.com> writes:

> mAnalysis eksisterer. Alle variable og objekter er initaliseret, ingen
> nullpointers nogle steder.

Link til komplet testeksempel, tak.
--
Thorbjørn Ravn Andersen


Malte (17-09-2005)
Kommentar
Fra : Malte


Dato : 17-09-05 23:39

Janus wrote:
> Hej NG!

Uanset forklaringen ville jeg foreslå IKKE at have enslydende
metodenavne og variable (addTSB i dette tilfælde). Det vil på sigt
forvirre både dig og dem, som skal vedligeholde koden.

Malte (17-09-2005)
Kommentar
Fra : Malte


Dato : 17-09-05 23:57

Janus wrote:
> Hej NG!
>

Uden at se hele din kode er det svært at se hvad der går galt. Jeg
googlede lidt:

http://mindprod.com/jgloss/nestedclasses.html

og fandt flg. lille afsnit, som måske hjælper:

<quote>
You might imagine that inner classes are merely a scope mechanism, that
they are independent classes, visible only to the outer class. Not so.
For every inner class object there must exist an associated outer class
object. You can't create inner class objects without first creating an
outer class object. You must create inner class objects in instance
methods so that this implicitly gives you the corresponding outer class
object.</quote>

Janus (18-09-2005)
Kommentar
Fra : Janus


Dato : 18-09-05 02:33

Malte wrote:
> Janus wrote:
>
>> Hej NG!
>>
>
> Uden at se hele din kode er det svært at se hvad der går galt. Jeg
> googlede lidt:
>
> http://mindprod.com/jgloss/nestedclasses.html
>
> og fandt flg. lille afsnit, som måske hjælper:
>
> <quote>
> You might imagine that inner classes are merely a scope mechanism, that
> they are independent classes, visible only to the outer class. Not so.
> For every inner class object there must exist an associated outer class
> object. You can't create inner class objects without first creating an
> outer class object. You must create inner class objects in instance
> methods so that this implicitly gives you the corresponding outer class
> object.</quote>

Ovenstående er logisk nok: Man kan ikke ha' en inner class uden en outer
/encapsulating class.

Jeg prøver at illustrere mit problem bedre:

public abstract class AbstractClass {
   private JButton button;
   
   public AbstractClass() {
      button = new JBtton("Press me, please");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent event) {
             abstractMethod(getData());
         }
      }
   }

   public abstract abstractMethod(Data d);

   private Data getData() {
      return new Data();
   }
}


....


public class ConcreteClass {
   
   ...

   AbstractClass ac = new AbstractClass() {
      abstractMethod(Data d) {
         contrecte_HandleData(d);
      }
   }
   
   private void contrete_HandleData(Data d) { // §§§
      // whatever
   }
}


-og det er så her filmen knækker. Metoden contrete_HandleData() med den
anonymt instantierede Data fra getData() kan ikke kaldes, resulterer i
en NullPointerException (endda i første linie i metoden, markeret med
§§§-tegnene).
Men dette her virker perfekt:

public abstract class AbstractClass {
   private JButton button;
   private Data d;
   
   public AbstractClass() {
      button = new JBtton("Press me, please");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent event) {
             abstractMethod(d);
         }
      }
   }

   private Data getData() {
      d = new Data();
      return d; // superfluous
   }
}

- sammen med samme ConcreteClass. Giver det nogen mening??


Hej fra Janus



--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Janus (18-09-2005)
Kommentar
Fra : Janus


Dato : 18-09-05 02:37

Janus wrote:

<snip: kode>

Ja, der mangler lidt bogstaver og "void" hist og her, men det er skrevet
kl meget ud fra hovedet... indsæt dem selv, problemstillingen er den
samme, altså det er ikke syntaxfejl jeg roder med :)
Thank God for den løbende syntaxtjekker i Eclipse.

Hej fra Janus


--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Janus (18-09-2005)
Kommentar
Fra : Janus


Dato : 18-09-05 09:20

For mange forstyrrende småfejl i tidl posting, jeg prøver igen:


public class ConcreteClass {

...

AbstractClass ac = new AbstractClass() {
abstractMethod(Data d) {
contrecte_HandleData(d);
}
}

private void contrete_HandleData(Data d) { // §§§
doDataStuff(d)
}
}


// Nedenstående version 1 af AbstractClass får contrece_HandleData(Data
d) til at kaste en NullPointerException i linien indikeret med §§§


public abstract class AbstractClass { // Version #1
private JButton button;

public AbstractClass() {
button = new JButton("Press me, please");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event)             
abstractMethod(getData());
}
}
}

private Data getData() {
return new Data();
}

public abstract void abstractMethod(Data d);
}


// Her er så version 2, denne udgave fungerer perfekt. Forskellen er
minimal og burde, efter mit hoved, ikke have indflydelse på hvordan
koden i ConcreteClass opfører sig.


public abstract class AbstractClass {
private JButton button;
private Data d;

public AbstractClass() {
button = new JButton("Press me, please");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
      getData();
   abstractMethod(d);
}
}
}

private Data getData() {
d = new Data();
return d; // superfluous
}

public abstract void abstractMethod(Data d);

}


Lasse Reichstein Nie~ (18-09-2005)
Kommentar
Fra : Lasse Reichstein Nie~


Dato : 18-09-05 11:00

Janus <nospam@nomail.com> writes:

> Hej NG!
>
> Her er en snip kode:

Hvis du kunne skære dit problem ned til et lille stykke kørende kode
der viser det, så vil det være meget nemmere at se fejlen.
<URL:http://www.physci.org/codes/sscce.jsp>

Du nævner senere at problemet sker ved kald til "funktionen"
AddTSB. Jeg kan ikke se en funktion der hedder AddTSB, men en
konstruktor. Hvor er den klasse definieret? Er det den koden
ligger i?

> private void tsbAddButtonPressedAction() {
>    AddTSB addTSB = new AddTSB(frame) {

Her laver du en ny variabel af type AddTSB, men bruger den ikke til
noget. Det typder på at det at oprette den (via new AddTSB()) har en
sideeffekt der gør den synlig. Det kan være et usundt træk at gøre
et objekt synligt i dets konstruktor, da de så måske bliver synligt
for resten af verden før det er helt initialiseret.

>       public void abstractCancelButtonPressed() {
>          closeWindow();
>       }
>       public void abstractOkButtonPressed(TSB tsb) {
>          System.out.println("TSB returned: "+ tsb);
>          addTSB(tsb);
>          updateTSBTable();
>          closeWindow();
>       }
>    };
> }
>    
> private void addTSB(TSB tsb) {
>    mAnalysis.addTSB(tsb);
> }
>
>
>
> Mit problem er så, at får en NullPointerException, når funktionen
> AddTSB kaldes (Ecplise 3.0.1, java 1.5.0_04):

Som sagt, der er ingen metode der hedder AddTSB, men der er en klasse
og dens konstruktor.

> Exception occurred during event dispatching:
> java.lang.NullPointerException
>    at gui.AddTSA.access$10(AddTSA.java:283)

Ok, så fejlen sker i metoden "access$10" i klassen "AddTSA".
Dollar-tegent tyder på at det er en genereret metode, sikkert noget
med en indre klasses, så du kan ikke finde den i din kode.

> Stacktracet er selvfølgelig længere end dette.

Ja, og hvad er der på de næste få linjer? Når den funktion jo netop
ikke findes.

>
> Linie 283 er: private void addTSB(TSB tsb) {

Altså er det nok noget kode der er indsat af compileren i begyndelsen
af den metode.

Metoden henviser til variablen "mAnalysis", som vi ikke kan se.
Ligger den i samme klasse eller (gætter jeg på) i en omsluttende
klasse, som addTSB-metodens klasse er en indre klasse i?

Hvis det er det sidste, så bliver det compilet så den indre klasse er
en klasse for sig selv, og den skal tilgå feltet i den omsluttende
klasse som alle andre felter i andre klasser. For at omgå at det måske
er privat, så er der genereret nogle nye "hemmelige" access-metoder,
og jeg gætter på at det er kaldet af sådan en der fejler.

Det kan igen skyldes at referencen bliver brugt i en konstruktor,
før referencen til det omsluttende element er blevet sat.


> tsb'en bliver printet som det skal i System.out.println'en, men
> hvorfor kan denne objektreference ikke nå til addTSB()? Jeg genererer
> TSB-objektet i AddTSB gennem abstractOkButtonPressed(createDataSet()),
> dvs. som "anonymt" (createDataSet returnerer objektet TSB), og det er
> dette der er problemet!

Bliver createDataSet kaldt inde fra en konstruktor?


Mere kode, ellers bliver det rent gætværk

/L
--
Lasse Reichstein Nielsen - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'

Janus (18-09-2005)
Kommentar
Fra : Janus


Dato : 18-09-05 12:46

Lasse Reichstein Nielsen wrote:

>
> Hvis du kunne skære dit problem ned til et lille stykke kørende kode
> der viser det, så vil det være meget nemmere at se fejlen.
> <URL:http://www.physci.org/codes/sscce.jsp>

Desværre, det kan jeg ikke.

>
> Du nævner senere at problemet sker ved kald til "funktionen"
> AddTSB. Jeg kan ikke se en funktion der hedder AddTSB, men en
> konstruktor. Hvor er den klasse definieret? Er det den koden
> ligger i?

Ja, det var så addTSB jeg mente.

>
>
>>private void tsbAddButtonPressedAction() {
>>   AddTSB addTSB = new AddTSB(frame) {
>
>
> Her laver du en ny variabel af type AddTSB, men bruger den ikke til
> noget.

Joda, bruger den ganske meget, det er en extention af JDialog. Brugeren
trykker på en knap der hedder Add TSB og dermed instantierer jeg
AddTSB(frame).


>
>>Exception occurred during event dispatching:
>>java.lang.NullPointerException
>>   at gui.AddTSA.access$10(AddTSA.java:283)
>
>
> Ok, så fejlen sker i metoden "access$10" i klassen "AddTSA".
> Dollar-tegent tyder på at det er en genereret metode, sikkert noget
> med en indre klasses, så du kan ikke finde den i din kode.

Ja, så langt er jeg også kommet selv, mit spørgsmål kunne vel også
omformuleres til "hvad står der EGENTLIG i linie 283 ??" :)

>
>
>>Stacktracet er selvfølgelig længere end dette.
>
>
> Ja, og hvad er der på de næste få linjer? Når den funktion jo netop
> ikke findes.
>

Resten af stacktracet er ikke interessant, det sporer udelukkende selve
knap-trykket, det har ingen indflydelse.


>
> Metoden henviser til variablen "mAnalysis", som vi ikke kan se.
> Ligger den i samme klasse eller (gætter jeg på) i en omsluttende
> klasse, som addTSB-metodens klasse er en indre klasse i?
>

mAnalysis er bare en slags datacontainer, har ikke nogle spøjse
fuktioner. Det mest ophidsende er en add() til en Vector.
Referencen til mAnalysis-objektet ligger i den klasse der instantierer
AddTSB.

> Hvis det er det sidste, så bliver det compilet så den indre klasse er
> en klasse for sig selv, og den skal tilgå feltet i den omsluttende
> klasse som alle andre felter i andre klasser. For at omgå at det måske
> er privat, så er der genereret nogle nye "hemmelige" access-metoder,
> og jeg gætter på at det er kaldet af sådan en der fejler.

mAnalysis bliver ikke tilgået fra konkretiseringen af den abstrakte
metode, det eneste der sker her er, at objektet tsb af typen TSB bliver
brugt som parameter til funktionen addTSB(TSB tsb) .. og det er dét der
går galt.

Hvordan er det nu liiiige det er med indre klassers adgang til den
omsluttende klasses felter og metoder? Mener der er nogle begrænsninger,
men det er vel noget der afsløres ved kompileringstidspunktet? Det her
vil i hvert fald gerne kompilere:

public class Test {
   
   private Object obj;
   
   private void fii() {
   }

   public Test() {
      obj = new Object();
      AbstractTest absTest = new AbstractTest() {
         public void foo() {
            obj.getClass();
            fii();
         }
      };
   }
}

public abstract class AbstractTest {

   public abstract void foo();
}



>
> Mere kode, ellers bliver det rent gætværk
>

Jeg har lavet et mere overskueligt eksempel på problemet andetsteds i
denne tråd. Indtil videre tak for dine kommentarer. Det er klart, at det
er noget med scopet på objektet tsb der er forkert. Det eksisterer i
bedste velgående inde i konkretiseringen af den abstrakte metode, men
kan åbenbart ikke refereres/parametiseres udenfor denne. Som sagt har
jeg fundet løsningen på problemet, men ikke fået defineret årsagen.
Løsningen kan du også se i det mere overskuelige eksempel.


> /L

/J :)


--
Kids, try this at home: http://www.legendsrpg.net/index.php?refid=799

Søg
Reklame
Statistik
Spørgsmål : 177579
Tips : 31968
Nyheder : 719565
Indlæg : 6409075
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste