Exception in thread "main" java.lang.NullPointerException

Holladerwaldelf

Grünschnabel
Dies ist vermutlich eine Standardfrage, ich habe allerdings nirgendwo im Netz eine weiterhelfende Antwort gefunden. Vielleicht kann mir hier ein netter Mensch weiter helfen.
Ich habe das unten stehende (einfache) Testprogramm geschrieben, bei dem nichts weiter passieren soll, als dass im TestField "TestF" (das eigentlich nichts anderes als ein JTextField ist) ein Text erscheint. Allerdings wird "TestF" nicht der public static void main - Methode erzeugt, sondern durch das AnzeigePanel (das nicht viel mehr als ein JPanel) "AusgabePanel" ("AusgabePanel" wird in der main-Methode erzeugt).
Beim Ausführen von
Code:
AusgabePanel.TestF.putData();
gibt es die "Exception in thread "main" java.lang.NullPointerException" - Fehlermeldung.
So wie ich es verstehe, ist also das "TestF"-Objekt noch gar nicht erzeugt oder der Pointer der "TestF"-Variablen zeigt noch nicht auf das Objekt (das aber schon da ist), deshalb kann die Methode des Objekts nicht ausgeführt werden.
Kann mir jemand helfen? Die Einbettung des "TestF"-Objekts in das "AusgabePanel"-Objekt ist beabsichtigt. Gibt es einen eleganten Weg da raus?




Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;



public class Test{

  public static void main ( String[] args )
  {
        JFrame AusgabeFrame = new JFrame();
        AusgabeFrame.setBounds(0,0,500,500);

        AnzeigePanel AusgabePanel = new AnzeigePanel();
        AusgabeFrame.getContentPane().add(AusgabePanel);
        
        AusgabePanel.TestF.putData();
        
        AusgabeFrame.setVisible(true);
   }

}


interface AnzeigeInt {
  void putData();
}


class AnzeigePanel extends JPanel implements AnzeigeInt {

  TestField TestF;

  AnzeigePanel() {

    super();

    JLabel TestLabel = new JLabel("Test");
    add(TestLabel);

    TestField TestF = new TestField();
    add(TestF);

  }

   public void putData(){
     TestF.putData();
   }

}


class TestField extends JTextField implements AnzeigeInt {

      TestField() {
        super();
      }

     public void putData(){
       setText("Hello World");
     }
}
 
Hallo,

Das einfachste wär, dass TestF im AusgabePanel nicht instanziert wurde.
Also schau dir bitte nochmal an, ob du auch wirklich das Attribut TestF neu instanziert hast:
Java:
testF = new TestF();
und nicht ein anderes TestF:
Java:
TestF testF = new TestF();
Übrigens: Attribute beginnen in Java für gewöhnlich mit einem Kleinbuchstaben zwecks Übersicht.. Ich hab's in meinem Beispiel mal angepasst (Beginn mit Kleinbuchstabe = Attribut; Beginn mit Großbuchstabe = Klasse).

Gruß,
Martin
 
Super, vielen Dank. Das war wirklich ein blöder Anfängerfehler :)

Wenn ich also in einer Klasse am Anfang eine Variable / ein Attribut deklariere, also in diesem Fall ein TestField mit Namen "testF", dann muss ich es im constructor mit
Code:
testF = new TestField();
instanzieren (oder "instantieren", wie schreibt man das auf Deutsch? :)), damit eine andere Methode, die diesen Bezeichner (also "testF") verwendet, auch auf das Objekt zurückgreifen kann.

Wenn ich mit
Code:
TestField testF = new TestField();
instanziere, dann wurde zu dem am Anfang der Klasse öffentlich deklarierten "testF" kein Objekt erzeugt (auf das "testF" zeigt), deshalb die "NullPointerException". Im Constructor von TestField wird dann eine neue Variable "testF" erzeugt (die auf das passende Objekt zeigt), auf die aber keine andere Methode zugreifen kann, weil diese Variable lokal ist.

Hab ich das richtig verstanden?
 
Moin,

Wenn ich also in einer Klasse am Anfang eine Variable / ein Attribut deklariere, also in diesem Fall ein TestField mit Namen "testF", dann muss ich es im constructor mit
Code:
testF = new TestField();
instanzieren (oder "instantieren", wie schreibt man das auf Deutsch? :)), damit eine andere Methode, die diesen Bezeichner (also "testF") verwendet, auch auf das Objekt zurückgreifen kann.

Wenn ich mit
Code:
TestField testF = new TestField();
instanziere, dann wurde zu dem am Anfang der Klasse öffentlich deklarierten "testF" kein Objekt erzeugt (auf das "testF" zeigt), deshalb die "NullPointerException". Im Constructor von TestField wird dann eine neue Variable "testF" erzeugt (die auf das passende Objekt zeigt), auf die aber keine andere Methode zugreifen kann, weil diese Variable lokal ist.
Hab ich das richtig verstanden?

also ... ich hab's nicht verstanden :D

Um es nochmal deutlich zu formulieren :

mit
Java:
TestField testF = new TestField();
wird an der Stelle des Aufrufs ein neues Objekt von Typ "TestField" mit dem Bezeichner "testF" erzeugt !

mit
Java:
testF = new TestField();
wird an der Stelle 'lediglich' ein Objekt instantiiert (ich denke, man schreibt es SO !! :D), das an anderer Stelle mit
Java:
TestField testF = null;
deklariert worden ist !!

Du musst drauf achten, dass Du immer das richtige Objekt im Zugriff hast! Ggf. kann es bspw. auch Methoden übergeben oder von Methoden zurückgegeben werden !

Gruß
Klaus
 
Zuletzt bearbeitet:
Ich denk, du hast's richtig verstanden, ja.. aber wurd ja grad nochmal schön erklärt.

Ansonsten noch ein Hinweis.. Es ist üblich, den Attributen einer Klasse nur privaten Zugang zu geben
Java:
private TestF testF;
und dann (öffentliche) Setter und Getter-Methoden zu schreiben.
Java:
public TestF getTestF() {
    return testF;
}
public void setTestF(TestF testF) {
    this.testF = testF;
}

Gruß,
Martin
 
Danke, eure Erläuterungen haben mir noch mal geholfen, dass das Ganze in meinem Kopf noch klarer wird. Ich scheine es tatsächlich richtig verstanden zu haben. :)

Eine Sache ist mir allerdings noch nicht völlig klar: Gibt es einen subtilen Unterschied zwischen "ein Objekt erzeugen" und "ein Objekt instantiieren"? Oder ist "instantiieren" "nur" Fachsprache für "erzeugen"?
 
Moin,

Eine Sache ist mir allerdings noch nicht völlig klar: Gibt es einen subtilen Unterschied zwischen "ein Objekt erzeugen" und "ein Objekt instantiieren"? Oder ist "instantiieren" "nur" Fachsprache für "erzeugen"?

hmm, "erzeugen" finde schwammig, weil es nichts sagt ....

Java:
// ein Objekt deklarieren
Object myObject;

// eine Instanz des Objekts erzeugen
myObject = new Object();

Erst nach dem Instantiieren ist IMHO wirklich der benötigte Speicher reserviert worden ...

tschüss
Klaus
 

Neue Beiträge

Zurück