Avatar billede chr.kj Nybegynder
10. december 2008 - 09:33 Der er 23 kommentarer og
1 løsning

Brug for hjælp til en NullPointerException

Jeg får en NullPointerException når jeg forsøger at tilknytte et person objekt til et hold objekt og jeg kan ikke helt selv gennemskue hvorfor dette sker.

Hele denne "tilmeldings procedure" spænder over 3 klasser og hvis vi starter i min GUI hvor jeg oprettet et objekt af typen
----------------------------------------------------------
Kontrol kontrol = new Kontrol();
----------------------------------------------------------

Herefter har jeg en knap med 2 indtastningsfelter:
----------------------------------------------------------

private void jToggleButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                             
int medlemsnr = Integer.parseInt( tfHentMedlemsNr1.getText() );
int holdnr = Integer.parseInt( tfTilmeldHoldnr.getText() );

kontrol.tilmeldMedlemTilHold(medlemsnr, holdnr);

JOptionPane.showMessageDialog(null, "Medlemmet er tilknyttet holdet\n Listen er gemt.");
    }
----------------------------------------------------------

I min Kontrol klasse har jeg følgende klasse variabler og konstruktør således, at jeg kan få fat i objekter fra andre klasser:
----------------------------------------------------------

public class Kontrol implements Serializable {

    private MedlemsListe medlemsRef;
    private HoldListe holdRef;
    private Hold holdTilmeldingsRef;

    public Kontrol()
    {
        medlemsRef = new MedlemsListe();
        holdRef = new HoldListe();
        holdTilmeldingsRef = new Hold();
    }
----------------------------------------------------------
I samme klasse har jeg min metode så jeg kan tilknytte et medlem til et hold:

//Metode til at kunne tilmelde sig et hold udfra holdnr og medlemsnr.
public void tilmeldMedlemTilHold( int medlemsnr, int holdnr )
{
//Henter et medlems objekt udfra medlemsnummer.
Medlem medlem = medlemsRef.hentMedlem( medlemsnr );

//Henter ønskede hold objekt via metoden hentAktuelHold() som ligger i HoldListe klassen
Hold hold = holdRef.hentAktuelHold( holdnr );

//Sammenkæder nu hold og medlemmer således at de samles
hold.tilmeldMedlemTilHold( medlem );
}
----------------------------------------------------------

I min MedlemsListe klasse (medlemsRef) har jeg lavet følgende metode som søger min ArrayListe igennem og hvis det indtastede medlemsnr. findes i listen returneres et medlems objekt:
----------------------------------------------------------
private ArrayList<Medlem> ml;

  public MedlemsListe()
  {
      ml = new ArrayList<Medlem>();
  }

public Medlem hentMedlem( int medlemsnr )
  {
    Medlem resultat=null;
    int i=0;
    while (i<ml.size() && medlemsnr!=ml.get(i).getMedlemsnr())
      i++;
    if (i<ml.size()) // Der er fundet
      resultat = ml.get(i);
    return resultat;
  }
----------------------------------------------------------

Samme metode findes i min HoldListe klasse, blot returneres et hold objekt hvis holdet findes i listen
----------------------------------------------------------
//Her initialiserer vi ArrayListen til vores hold
    private ArrayList<Hold> holdene;// = new ArrayList<Hold>();

    public HoldListe()
    {
        holdene = new ArrayList<Hold>();
    }

public Hold hentAktuelHold( int holdnr )
  {
    Hold resultat=null;
    int i=0;
    while (i<holdene.size() && holdnr!=holdene.get(i).getHoldnr())
      i++;
    if (i<holdene.size()) // Der er fundet
      resultat = holdene.get(i);
    return resultat;     
  }
----------------------------------------------------------
I min Hold klasse har jeg mn ArrayListe som indeholder listen over tilmeldinger. Her mener/tror jeg, at hele klassen kan være interessant at vise for at kunne få hjælp:
----------------------------------------------------------

public class Hold implements Serializable {

    private String dato;
    private String tid;
    private int holdnr;
    private String holdType;
    private int maxAntalDeltagere;
    private ArrayList<Medlem> holdTilmeldingsliste;

//Her laver vi vores konstruktør
public Hold()
{
holdTilmeldingsliste = new ArrayList<Medlem>();
}

public Hold( String dato, String tid, int holdnr, String holdType, int maxAntalDeltagere )
{
this.dato = dato;
this.tid = tid;
this.holdnr = holdnr;
this.holdType = holdType;
this.maxAntalDeltagere = maxAntalDeltagere;

}
   
public int getMaxAntalDeltagere()
{
return maxAntalDeltagere;
}

public int getHoldnr()
{
return holdnr;
}

public void tilmeldMedlemTilHold( Medlem obj )
{
holdTilmeldingsliste.add( obj );
}

public ArrayList<Medlem> getTilmeldinger()
{
return holdTilmeldingsliste;
}

//Her laver vi vores toString metode
public String toString()
{
return "Holdnr: " + holdnr + " - Hold type: " + holdType + "\nDato: " + dato + " - Tidspunkt: " + tid + "\nMax antal deltagere: " + maxAntalDeltagere + "\n\n";
    } 
}
----------------------------------------------------------
Som skrevet, kan jeg ikke forstå hvorfor jeg får denne nullPointerException og håber at der er en der kan hjælpe mig med at få løst dette.

På forhånd tak for hjælpen :)
Avatar billede erikjacobsen Ekspert
10. december 2008 - 09:42 #1
I hvilken linie får du din nullPointerException ?

Er der noget i listerne ?

Når fx public hentAktuelHold kan returnere null, så er det altid forkert at skrive:

  Hold hold = holdRef.hentAktuelHold( holdnr );
  hold.tilmeldMedlemTilHold( medlem );

Dvs. uden at teste for om hold blev null.
Avatar billede chr.kj Nybegynder
10. december 2008 - 09:54 #2
Hej Erik.

Jeg er rimelig sikker at der er noget i medlems- og holdlisten, da jeg starter med at indtaste data i dem, men bare for en sikkerheds skyld - Hvordan kan jeg testet at der rent faktisk er noget i dem?

Min Nullpointer kommer her:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at fitnesscenter.Hold.tilmeldMedlemTilHold(Hold.java:57)
        at fitnesscenter.FitnessCenterKontrol.tilmeldMedlemTilHold(FitnessCenterKontrol.java:76)
        at fitnesscenter.HovedMenu.jToggleButton2ActionPerformed(HovedMenu.java:713)

men kan teste om hold er null ved at lave en if-sætning eller er der andre måder dette kan/bør gøres på?
Avatar billede erikjacobsen Ekspert
10. december 2008 - 09:58 #3
I dette tilfælde vil du kunne gøre noget i retning af:

  Hold hold = holdRef.hentAktuelHold( holdnr );
  if (hold<>null) {
    hold.tilmeldMedlemTilHold( medlem );
  } else {
    //fx udskriv at holdet ikke findes
  }

Hvis fejlen opstår i metoden:

  public void tilmeldMedlemTilHold( Medlem obj )
  {
  holdTilmeldingsliste.add( obj );
  }

så kan det jo være fordi holdTilmeldingsliste er null. Den bliver kun sat til noget i den ene constructor, og ikke i den anden.
Avatar billede pidgeot Nybegynder
10. december 2008 - 09:59 #4
Du opretter kun holdTilmeldingsliste i din parameterløse constructor - din constructor med parametre opretter den ikke. Sørg for at den gør det - nu er det noget tid siden jeg har arbejdet i Java, så kan ikke huske præcist hvordan, men du skulle kunne skrive en linje så din constructor med parametre kalder (og dermed udfører koden) i den parameterløse udgave.
Avatar billede pidgeot Nybegynder
10. december 2008 - 10:00 #5
(...og det var så lige det med at huske at opdatere inden man trykker Send...)
Avatar billede chr.kj Nybegynder
10. december 2008 - 10:12 #6
@Erik

Nu har jeg skrevet:

if (hold.equals(null))
        {
            System.out.println("Intet hold fundet");
        } else {
            hold.tilmeldMedlemTilHold( medlem );
        }
men den kommer stadig med nullpointer og ikke min Sys.out fejl?

@pidgeot Dvs. at jeg også skal skrive:

holdTilmeldingsliste = new ArrayList<Medlem>();

i min konstruktør med parametre?
Avatar billede erikjacobsen Ekspert
10. december 2008 - 10:20 #7
Den første gør ingen forskel, for det var ikke der fejlen var denne gang ;)

Den med constructoren: Nej, lad være med at gentage koden med new. Nederst/øverst i din constructor tilføjer du linien
    this();
som vil kalde den parameterløse constructor (hvis jeg husker Java rigtigt).

DRY-princippet: Don't Repeat Yourself.
Avatar billede erikjacobsen Ekspert
10. december 2008 - 10:21 #8
Nederst/øverst i din constructor **med parametre** tilføjer du linien ...
Avatar billede schwarz84 Nybegynder
10. december 2008 - 10:24 #9
Du skal skrive
if (hold == null)
I stedet for
if (hold.equals(null))

Den sidste forsøger at kalde metoden equals på objektet hold (som ikke findes) med argumentet null, hvilket selvfølgelig går galt...
Avatar billede chr.kj Nybegynder
10. december 2008 - 10:40 #10
this(); virkede men for at forstå det korrekt, så gør this(); at mit objekt i min parameterløse konstruktør bliver dannet når min anden konstruktør med parametre initialiseres, eller hvordan kan dette forstås?

Jeg får desværre stadig nullpointer og ingen andre fejl selvom jeg ændrede equals med ==

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at fitnesscenter.Hold.tilmeldMedlemTilHold(Hold.java:58)
        at fitnesscenter.Kontrol.tilmeldMedlemTilHold(FitnessCenterKontrol.java:78)

Hold.tilmeldMedlemTilHold er :

public void tilmeldMedlemTilHold( Medlem obj )
    {
      holdTilmeldingsliste.add( obj );
    }

Så det er måske fordi min medlems objekt ikke findes?
Avatar billede erikjacobsen Ekspert
10. december 2008 - 10:43 #11
Må vi se hvad du gør?
Avatar billede chr.kj Nybegynder
10. december 2008 - 10:50 #12
Hmmm.. Spøjst..

Efter at have slettet min liste og oprettet den igen kan jeg godt tilknytte medlemmet til holdet?? Fatter ikke hvad der er sket?

@erik - hvad vil du gerne se?
Avatar billede erikjacobsen Ekspert
10. december 2008 - 10:55 #13
Jeg ville fx se om du havde anbragt "this();" rigtigt.
Avatar billede chr.kj Nybegynder
10. december 2008 - 11:01 #14
Her er klassevariablerne og mine 2 konstruktører i klassen Hold

public class Hold implements Serializable {

    private String dato;
    private String tid;
    private int holdnr;
    private String holdType;
    private int maxAntalDeltagere;
    private ArrayList<Medlem> holdTilmeldingsliste;

    //Her laver vi vores konstruktør

    public Hold()
    {
        holdTilmeldingsliste = new ArrayList<Medlem>();
    }

    public Hold( String dato, String tid, int holdnr, String holdType, int maxAntalDeltagere )
    {
        //Her kalder vi den parameterløse konstruktør med this();
        this();
        this.dato = dato;
        this.tid = tid;
        this.holdnr = holdnr;
        this.holdType = holdType;
        this.maxAntalDeltagere = maxAntalDeltagere;
    }
Avatar billede erikjacobsen Ekspert
10. december 2008 - 11:20 #15
Og det er i orden ;)  Det var bare fordi du blev ved med at få samme fejl.
Avatar billede chr.kj Nybegynder
10. december 2008 - 14:06 #16
Super.. Tusind tak, endnu engang for din hjælp Erik :)

Jeg ved ikke rigtig hvem af jer, udover erik, der fortjener disse point.. Jeg ved at erik ikke samler på dem, og pidgeot fik mig noget af vejen ved at gøre min opmærksom på manglende initialisering af min ArrayListe i min konstruktør. Anyways. Smid et svar og tak for hjælpen alle sammen :)
Avatar billede chr.kj Nybegynder
10. december 2008 - 14:08 #17
Hmmm.. Ok.. der var jeg måske for hurtig ude...

Jeg kan af en eller anden årsag tilknytte medlemmer til et hold nr. der slet ikke er oprettet i min holdliste?..??
Avatar billede chr.kj Nybegynder
10. december 2008 - 14:28 #18
Ok.. tror jeg er ved at være træt nu :/

Jeg har lavet følgende validering af min metode:

//Metode til at kunne tilmelde sig et hold udfra holdnr og medlemsnr.
    public void tilmeldMedlemTilHold( int medlemsnr, int holdnr )
    {
        //Henter et medlems objekt udfra medlemsnummer.
        Medlem medlem = medlemsRef.hentMedlem( medlemsnr );
        if (medlem != null)
        {
            System.out.println("Medlem fundet");
        } else {
            System.out.println("Medlem ikke fundet");
        }

        //Henter ønskede hold objekt via metoden hentAktuelHold() som ligger i HoldListe klassen
        Hold hold = holdRef.hentAktuelHold( holdnr );
        if (hold != null)
        {
            //Sammenkæder nu hold og medlemmer således at de samles
            hold.tilmeldMedlemTilHold( medlem );
            System.out.println("Hold fundet");
        } else {
            System.out.println("Intet hold fundet");
        }
    }
og der kan jeg se at den både finder et medlems og et hold objekt så jeg kan vel gå udfra at disse sammenkædes i min Arrayliste holdTilmeldingsliste - ik?
Avatar billede chr.kj Nybegynder
10. december 2008 - 14:42 #19
Har lavet min ArrayListe holdTilmeldingsliste public så jeg kan lave en size(); i min Kontrol klasse:

//Metode til at kunne tilmelde sig et hold udfra holdnr og medlemsnr.
    public void tilmeldMedlemTilHold( int medlemsnr, int holdnr )
    {
        //Henter et medlems objekt udfra medlemsnummer.
        Medlem medlem = medlemsRef.hentMedlem( medlemsnr );
        if (medlem != null)
        {
            System.out.println("Medlem fundet");
        } else {
            System.out.println("Medlem ikke fundet");
        }

        //Henter ønskede hold objekt via metoden hentAktuelHold() som ligger i HoldListe klassen
        Hold hold = holdRef.hentAktuelHold( holdnr );
        if (hold != null)
        {
            //Sammenkæder nu hold og medlemmer således at de samles
            hold.tilmeldMedlemTilHold( medlem );

            System.out.println("Hold fundet");
            System.out.println( holdTilmeldingsRef.holdTilmeldingsliste.size() );
        } else {
            System.out.println("Intet hold fundet");
        }
    }

Og her kan jeg se at min liste ikke bliver størrer?

Min metode i Hold klassen som
            hold.tilmeldMedlemTilHold( medlem );
referer til ser sådan ud:

public void tilmeldMedlemTilHold( Medlem obj )
    {
      holdTilmeldingsliste.add( obj );
    }

Er der en der kan se hvorfor der ikke tilføjes et objekt til min liste?

På forhånd tak :)
Avatar billede erikjacobsen Ekspert
10. december 2008 - 14:48 #20
Du laver en ny liste hver gang du siger new Kontrol(); - jeg ved ikke om det derfor.
Avatar billede chr.kj Nybegynder
10. december 2008 - 14:53 #21
Burde samme så ikke gøre sig gældende ved medlemmer og hold?
Avatar billede chr.kj Nybegynder
12. december 2008 - 16:11 #22
Fand ud af det med hjælp fra læren :)

De af jer der hjalp mig må gerne smide et svar så fordeler jeg point mellem jer.
Avatar billede erikjacobsen Ekspert
12. december 2008 - 18:04 #23
Ingen point til mig, tak.
Avatar billede chr.kj Nybegynder
06. januar 2009 - 13:36 #24
Lukker - Tak for hjælpen :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester