Compiler-Fehler Java suckt - java.lang.NullPointerException

MyOuzo

Mitglied
Hallo Forummember,

wie der Titel schon beschreibt, gibt mir mein Compiler "java.lang.NullPointerException" aus. Was ich nicht nachvollziehen kann da Java überhaupt keine Pointer enthällt / benutzt. Hier mein Code zum anschauen:

Java:
private class punkte
{
  ArrayList<Integer> xC;
  ArrayList<Integer> yC;
  
  int xD;
  int yD;
  
  punkte()
  {
  xC.add(0);
  yC.add(0);
  
  this.xD = 0;
  this.yD = 0;
  }
  
  public void setPunkte(int laenge, int w, int h, int x, int y)
  {
    for(int loop = 0-(laenge/2); loop+(laenge/2) > laenge; loop++)
      {
        xC.add(w);
        yC.add(h+loop);
      }
    int xD = x;
    int yD = y;
  }
  
  public void replace()
  {
    xC.remove(0); yC.remove(0);
    
    xC.add(xC.get(xC.size()-1)+xD);
    yC.add(yC.get(yC.size()-1)+xD);
  }
  
  public void resetD(int newx, int newy)
  {
    xD = newx;
    yD = newy;
  }
  
  public void snake()
  {
    for(int loop = 0; loop > xC.size()-1; loop++)
    {
      point(xC.get(loop), yC.get(loop));
    }
  }
  
}

punkte p = new punkte();

void setup()
{ 
  int w = width/2;
  int h = height/2;
  
  int laenge = 9 - 1;
  
  int x = -1;
  int y = 0;
  
  p.setPunkte(laenge, w, h, x, y);
  size(640,360);
  background(0);
}

void draw()
{
  stroke(255,150,10);
  p.snake();
  p.replace();
  background(0);
}

void keyPressed()
{
  switch(keyCode)
  {
    case 38: p.resetD(-1, 0); break; // UP
    case 40: p.resetD(1, 0); break;  // DOWN
    case 37: p.resetD(0, -1); break; // 3RIGHT
    case 39: p.resetD(0, 1); break; // RIGHT 
  }
}

Als Entwicklungsumgebung wird "Processing" verwendet. Das Programm soll später ein "Snake" Spiel werden. Variablen+Felder(Eigenschaften) und Funktionen(Methoden) habe ich ( wie gewohnt in C++ ) in Klassen "gepackt".
 
Zuletzt bearbeitet:
Sollte eine Zeilenangabe angegeben sein, wäre es oft sehr hilfreich, wenn man diese mitpostet.

Java:
ArrayList<Integer> xC;
ArrayList<Integer> yC;

Du erstellst von diesen beiden Listen nie ein Objekt. Ich denke hierbei liegt auch der Fehler. Du weist der Variablen zwar einen Datentyp zu, aber initialisierst sie nicht.

Java:
 ArrayList<Integer> yC = new ArrayList<Integer>();
// usw
 
Zuletzt bearbeitet:
Das wäre mir neu ( außer bei C++ 11), dass man die Initialisierung direkt bei der Deklaration stattfinden lassen kann, bzw. außerhalb des Konstruktors. Der Compiler spuckt mir jetzt einen anderen Fehler aus: "ArrayIndexOutOfBoundsException: -1"

Zeile 33:

[JAVA=33]xC.add(xC.get(xC.size()-1)+xD);[/code]

Wenn xC.size() z.B 15 zurückgibt, ist dann der letzte Index der Liste 14, oder nicht ?
 
Zuletzt bearbeitet:
Da wir nicht bei C sind, sondern in Java, kannst du einfach Java Krams machen und das geht dann einfach.

Beispielsweise kannst du AUSSERHALB eines Konstruktors eine Klassenvariable bei der Deklaration initialisieren.

zu deinem ArrayOutOfBounds - wie groß ist denn xD?
Wenn xD > 0 ist bist du hinter dem letzten Element. (du hast bei Größe 15 den letzten Index mit der NUmmer 14, addierst da aber was drauf (xD) und hast dann einen Index >14...)
 
Zur Veranschaulichung:
xC.get(xC.size()-1) = i

also wäre der code : xC.add(i+xD)

der angegebene Index ist also IMMER das was xC.size zurückgibt minus 1. Nicht von xD abhängig.

JCODA, size wird niemals 0 zurückgeben, solange replace() nicht vor setPunkte() aufgerufen wird. Das hier nicht zutrifft. Nur wenn die Liste KEINEN Wert hat würde 0 zurückgegeben werden, aber die Instanzvariablen werden ja bei dem Konstruktor initialisiert ( spätestens )

Phash, xD wird in diesem Fall -1 zugewiesen und yD entsprechend 0.
 
Zuletzt bearbeitet:
gewöhne dir auch bitte die korrekte verwendung des wortes "compiler" an ... denn der compiler wird dir sicherlich NIE eine RuntimeException werfen ... sondern höchstens compiler-errors und -warnings

alles was zur laufzeit passiert, also NPE und AIOOB, kommt vom interpreter
 
JCODA, size wird niemals 0 zurückgeben, solange replace() nicht vor setPunkte() aufgerufen wird. Das hier nicht zutrifft. Nur wenn die Liste KEINEN Wert hat würde 0 zurückgegeben werden, aber die Instanzvariablen werden ja bei dem Konstruktor initialisiert ( spätestens )

Wenn du an der betreffenden Stelle die genannte Exception bekommst, dann ist xC.size() 0. Punkt. Wenn du sagst, das kann nicht sein, dann irrst du dich. Du könntest beispielweise vor der betreffenden Stelle die size ausgeben, um ganz sicher zu gehen.
Woher kannst du sicher sein, daß replace() nicht doch vor setPunkte() aufgerufen wird? Vielleicht wird ja auch draw() aufgerufen?
Ich hätte ja selber ein bisschen probiert, aber dein Code ist so nicht verwendbar. Offenbar fehlt die umgebende Klasse komplett. Nur so ist erklärbar, daß die einzige Klassendeklaration private ist, und alles was in deinem Schnipsel nach Zeile 51 ist, ausserhalb einer Klassendefinition steht.
 
Mittlerweile ist mir selbst aufgefallen was daran falsch war. Der eigendliche Fehler befindet sich nicht in Zeile 33 sondern in 20, da ein größer- anstatt ein kleiner-Operator verwendet wurde.
Harry nein mein Code ist nicht (mehr) unbrauchbar:

Java:
private class punkte
{
  ArrayList<Integer> xC = new ArrayList<Integer>();
  ArrayList<Integer> yC = new ArrayList<Integer>();
  
  int xD;
  int yD;
  
  punkte()
  {
  xC.add(0);
  yC.add(0);
  
  this.xD = 0;
  this.yD = 0;
  }
  
  public void setPunkte(int laenge, int w, int h)
  {
    for(int loop = 0-(laenge/2); loop+(laenge/2) < laenge; loop++)
      {
        xC.add(w);
        yC.add(h+loop);
      }
  }
  
  public void replace()
  {
    xC.remove(0); yC.remove(0);
    
    xC.add(xC.get(xC.size()-1)+xD);
    yC.add(yC.get(yC.size()-1)+yD);
  }
  
  public void resetD(int newx, int newy)
  {
    xD = newx;
    yD = newy;
  }
  
  public void snake()
  {
    for(int loop = 0; loop < xC.size()-1; loop++)
    {
      point(xC.get(loop), yC.get(loop));
      println("X: " + xC.get(loop) + "  Y: " + yC.get(loop));
    }
  }
  
}

punkte p = new punkte();

void setup()
{ 
  int w = 360;
  int h = 180;
  
  int laenge = 9 - 1;
  
  p.setPunkte(laenge, w/2, h/2);
  size(w,h);
  background(0);
}

void draw()
{
  background(0);
  stroke(255,150,10);
  strokeWeight(5);
  p.snake();
  p.replace();
}

void keyPressed()
{
  switch(keyCode)
  {
    case 38: p.resetD(0, -1); break; // UP
    case 40: p.resetD(0, 1); break;  // DOWN
    case 37: p.resetD(-1, 0); break; // 3RIGHT
    case 39: p.resetD(1, 0); break; // RIGHT 
  }
}

Wenn in Zukunft mit dem Code nichts stimmen sollte und ich keine Erklärung dafür habe melde ich mich wieder, jetzt lehnt euch zurück und schaut das Fußballspiel.
 
Zuletzt bearbeitet:
Ich habs gegoogelt, danke für den Hinweis 😉

By the way, gibt es eine Möglichkeit bei "ArrayList" direkt das letzte Element aufzurufen ( nicht(!) das este mit dem Index 0 )
 
Zuletzt bearbeitet:
Java:
List<String> l = new ArrayList<>();
l.get(l.size() - 1);

MIt der letzten Zeile bekommst du das Element an letzter stelle
 
Zuletzt bearbeitet:

Zurück
Oben