Wieso java.lang.StackOverflowError (minimal programm)

Fastkiller

Mitglied
Hi!

Ich steh gerade voll an =(

Ich hab hier mal schnell ein kleines beispiel geschrieben das den selben fehler produziert wie mein eigentliches programm...

Beschreibung: Ich hab 2 Klassen (graphics1, test). In jeder Klasse erzeuge ich ein Objekt um auf die Attribute , Methoden der anderen klasse zugreifen zu können. Allerdings bekomm ich folgende Fehlermeldung beim ausführen:


Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.awt.windows.WToolkit.getScreenInsets(Native Method)
at sun.awt.windows.WToolkit.getScreenInsets(Unknown Source)
at java.awt.Window.init(Unknown Source)
at java.awt.Window.<init>(Unknown Source)
at java.awt.Frame.<init>(Unknown Source)
at java.awt.Frame.<init>(Unknown Source)
at javax.swing.JFrame.<init>(Unknown Source)
at test.graphics1.<init>(graphics1.java:29)
at test.test.<init>(test.java:5)...........
.....

graphics1 Klasse:

Code:
package test;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;

public class graphics1 extends javax.swing.JFrame {
	private JButton jButton1;
	
	test t1 = new test();

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				graphics1 inst = new graphics1();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public graphics1() {
		super();
		initGUI();
	}
	
	private void initGUI() {
		try {
			BorderLayout thisLayout = new BorderLayout();
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			getContentPane().setLayout(thisLayout);
			{
				jButton1 = new JButton();
				getContentPane().add(jButton1, BorderLayout.CENTER);
				jButton1.setText("jButton1");
				jButton1.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent evt) {
						jButton1ActionPerformed(evt);
					}
				});
			}
			pack();
			setSize(400, 300);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void jButton1ActionPerformed(ActionEvent evt) {
		System.out.println("jButton1.actionPerformed, event="+evt);
		t1.test();
}

}

test Klasse:

Code:
package test;
import src.Graphics;

public class test {
	graphics1 g1= new graphics1();	
	

	
	void test(){
		
		g1.setTitle("hallo");
	}
	
}

Ich hoffe ihr könnt mir helfen! =)

MFG
 
Gar nichts, dass ist jetzt einfach nur ein sinnloses Beispiel von mir, dass mir die Selbe Fehlermeldung reproduziert wie in meinem anderen Programm. So muss ich nicht den ganzen unübersichtlichen code posten =)
 
Naja, das is ja relativ logisch. Du instantiierst graphics1. Bevor der Construktor gerufen wird werden oben die Variableninitialisierungen durchgeführt. Darin wird eine neue Instanz von test erzeugt. Bevor dessen Konstruktor gerufen wirde werden ebenfalls wieder die Variablen in test initialisiert. Dort wird wieder der Konstruktor von graphics1 gerufen und das spiel geht von vorn los.

Gruß
Ollie
 
Aha Ok danke! jetzt weiß ich wenigstens wieso er mir nen stackOverflow ausgibt..

Wie kann ich das problem jetzt allerdings umgehen?
 
Ich seh halt den Sinn in der doppelseitigen Verkettung nicht (schon gar nicht, wenn sie immer wieder neue Instanzen erzeugt). Was soll denn test eigentlich tun?

Grundsätzlich wäre ich vorsichtig mit direkten Variableninitialisierungen. Wenn du die im Konstruktor gemacht hättest, wäre es sicher einfach zu sehen gewesen. Eigentlich ist der Konstruktor auch immer das erste, was nach der Variablendeklaratio kommt. Durch die main Methode zwischen Variablendeklaration und Konstruktor wars vielleicht nicht auf den ersten Blick zu entdecken.

Gruß
Ollie

PS: Klassennamen schreibt man groß! ;)
 
Naja die Klasse Test soll eigentlich gar nichts tun. Ich will nur nicht die ganzen Methoden etc in die Graphics klasse schreiben. Die Test Klasse dient dann eigentlich nur zum Aufruf der Methoden die da drin sind.
 
Falls ich dich jetzt richtig verstanden habe sollte das funktionieren:

Code:
package test;
import src.Graphics;

public class test {
    graphics1 g1;    
    

    
    void test(graphics1 g1){
        this.g1 = g1;
        g1.setTitle("hallo");
    }
    
}


Code:
package test;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;

import javax.swing.WindowConstants;
import javax.swing.SwingUtilities;

public class graphics1 extends javax.swing.JFrame {
    private JButton jButton1;
    
    test t1;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                graphics1 inst = new graphics1();
                inst.setLocationRelativeTo(null);
                inst.setVisible(true);
            }
        });
    }
    
    public graphics1() {
        super();
        initGUI();
        t1 = new test(this);
    }
    
    private void initGUI() {
        try {
            BorderLayout thisLayout = new BorderLayout();
            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            getContentPane().setLayout(thisLayout);
            {
                jButton1 = new JButton();
                getContentPane().add(jButton1, BorderLayout.CENTER);
                jButton1.setText("jButton1");
                jButton1.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent evt) {
                        jButton1ActionPerformed(evt);
                    }
                });
            }
            pack();
            setSize(400, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private void jButton1ActionPerformed(ActionEvent evt) {
        System.out.println("jButton1.actionPerformed, event="+evt);
        t1.test();
}

}
 
Jo schaut vernünftiger aus. Aber BITTE schreib die Klassennamen groß! Ich denk die ganze Zeit void test wäre eine Methode ^^ ;).

Gruß
Ollie
 
Zurück