# java.lang.StackOverflowError Debugging?



## JayJay (10. Jun 2007)

Hallo,

und zwar bekomm ich in der Konsole nur diese Fehlermeldung:

"java.lang.StackOverflowError"

Wo das aufgetreten ist, wird nicht beschrieben - in meinem Root verzeichnis der Klassen finde ich auch keine debug-datei, die erstellt werden sollte?

Kann ich das irgdnwo einstellen, dass wir mehr gesagt wird?


----------



## kleiner_held (10. Jun 2007)

Die Fehlermeldung ist nur dann derartig verkürzt, wenn du selbst den Fehler abfängst und verkürzt ausgibst. Normalerweise gibt dir die JVM immer den gesamten Stacktrace mit aus (was bei einem StackOverflowError naturgemäß nicht grade wenig ist).


----------



## HLX (11. Jun 2007)

kleiner_held hat gesagt.:
			
		

> Die Fehlermeldung ist nur dann derartig verkürzt, wenn du selbst den Fehler abfängst und verkürzt ausgibst. Normalerweise gibt dir die JVM immer den gesamten Stacktrace mit aus (was bei einem StackOverflowError naturgemäß nicht grade wenig ist).



Nicht unbedingt. Errors sind schwerwiegend, d.h. die JVM ist instabil und arbeitet u.U. nicht mehr ordnungsgemäß. Errors sollten daher auch niemals abgefangen werden.

StackOverflowErrors treten oft bei Endlosschleifen auf. Überprüf doch mal deine Schleifen/Rekursionen. Falls du keinen Debugger hast, schreibe Ausgaben in die Schleifen.


----------



## JayJay (11. Jun 2007)

Hi, danke für die Informationen. Den Fehlre hab ich gefunden war eine komische while schleife.

Woher bekomm ich einen DEbugger? Ich benutze Eclipse?


----------



## Murray (11. Jun 2007)

Dann hast du schon einen Debugger.


----------



## licht400 (31. Jul 2007)

Hallo, habe ein StackOverflowError Problem.

Habe in der Klasse fesnter die main drin. da wird die Klasse aktionen aufgerufen.


```
public class fenster {
    public static void main(String[] args) throws Exception {
        aktionen f = new aktionen();
        f.setSize(800, 600);
        f.setVisible(true); 
       
        
    }
```

Aktionen sieht so aus:

```
public class aktionen {

    private design d;
    private tree t;
    private suchindex si;
    private suchfunction sf;

       public aktionen() throws DocumentException {
        d = new design();
        t = new tree();
        si= new suchindex();
        sf= new suchfunction();
       
    } 
}
```

der FEHLER kommt einmal bei der main wo f aufgerufen wird und verweist dann
auf die klasse aktionen.
Darf man keine 4 konstruktoren machen? woher kommt da dieses StackOverflowError?

danke für die Hilfe!


----------



## SlaterB (31. Jul 2007)

mach das doch Schritt für Schritt, kommentiere t, si und sf auf und erstelle nur d,
kommt es zum Error, dann weiter untersuchen, was macht der design-Konstruktor?,
ansonsten einen der anderen drei, 

mit etwas Pech hast du einen ganz vertrackten Fehler, der nur auftritt, wenn mindestens zwei (oder mehr) der vier erzeugt werden 
aber man muss ja nicht mit dem schlimmsten rechen,


der Fehler ist nun entweder völlig unabhängig vom bisherigen Code irgendwo einzeln in einer der Subklassen,

oder wahrscheinlicher: du hast irgendwelche Schleifen bei der Initialisierung:
aktionen erzeugt ein design-Objekt, 
design  erzeugt ein aktionen -Objekt,
aktionen erzeugt ein design-Objekt, 
usw. bis in alle Ewigkeit 

schaue dir alle Konstruktoren und auch automatisch erzeugte Exemplar- + statische Variablen an

---------

hilfreich bei sowas ist oft, einen leeren Konstruktor zu definieren,
und enthaltene Objekte mit einer init()-Operation später zu erzeugen,

hilft aber auch nicht unbedingt, wenn init() praktisch automatisch nach dem Konstruktor gerufen wird, ne komplizierte Sache


-----------

Klassen groß schreiben!


----------



## deleted (31. Jul 2007)

Ich würde auch mal nachschaun. ob du irgendwo rekursiv gearbeitet hast.
Fehler in Rekursiven Methoden (Endlosrekursion) ist eine sehr "beliebte" Quelle für StackOverflows in Java...


----------



## licht400 (31. Jul 2007)

danke..also werd jetz dem rat vom Slater befolgen und jede klasse untersuchen..hatte es nochmal geändert, aber wieder StackOverflowError...die klassen stehen jetz grob unten..
könnt ja an der DocumentException liegen, aber die will Netbeans ständig machen!
(nagut, ich mach das mal einzeln)



> public class fenster {
> public static void main(String[] args) throws Exception {
> design d = new design(a);
> }
> }





> public aktionen() throws DocumentException {
> 
> t = new tree(d);
> si = new suchindex(sf,t);
> ...





> public design(aktionen a) throws DocumentException{
> this.a = a;
> 
> frame.setSize(800, 600);
> ...





> public suchfunction(tree t) throws DocumentException{
> this.t = t;
> d = new design(a);
> a = new aktionen();
> }





> public suchindex(suchfunction sf, tree t) throws DocumentException{
> d = new design(a);
> this.sf =sf;
> this.t = t;
> }





> public tree(design d) throws DocumentException{
> this.d =d;
> }


----------



## deleted (31. Jul 2007)

Dass es daran liegt, dass da irgendeine Exception geworfen liegt, denke ich mal nicht.
Außer, SUN hat irgendwo in Java ein Speicherleck.
Aber normal ist das bei einer Exception extrem unwahrscheinlich.

Ich denke ehr, du hast einen Fehler in einer deiner Methoden.
Dein Stack läuft über.
Testen kannst du das ganz bewusst mal so:


```
public class MopsKamInDieKueche {

	private static void mopsGrabstein(int count) {
		System.out.println("Ein Mops kam in die Kueche und stahl dem Koch ein Ei, da nahm der Koch den Loeffel, und schlug den Mops enzwei. Da kamen viele Moepse und gruben ihm nen Grab, und setzen ihm nen Grabstein, worauf geschrieben stand:");
		System.out.println("Durchlaufcount++);
		mopsGrabstein(count);
	}
	
	public static void main(String[] args) {
		System.out.println("Ein Mops kam in die Kueche und stahl dem Koch ein Ei, da nahm der Koch den Loeffel, und schlug den Mops enzwei. Da kamen viele Moepse und gruben ihm nen Grab, und setzen ihm nen Grabstein, worauf geschrieben stand:");
		int count = 1;
		mopsGrabstein(count);
	}

}
```

nach ein paar Sekunden Ausführzeit (je nach Prozessor) krepiert er an diesem Fehler:

Exception in thread "main" java.lang.StackOverflowError

und zwar bei mir nach Durchlauf 3952.

Je mehr Anweisungen die Methode enthält, desto ehr stürzt er ab.

Was du mal versuchen könntest ist, ob du irgendwie deiner JVM einen größeren Stack zuweisen kannst.
Leider weiß ich grad nicht wie das geht (habe sowas noch nie gebraucht).

Denn es könnte ja durchaus sein, dass du ja WILLST, dass so eine Operation ausgeführt wird (bei 4000 Mopsgrabsteienen, die du haben willst, würde die JVM mit Fehler terminieren, obwohl dein Programm eigentlich korrekt wäre).


----------



## licht400 (31. Jul 2007)

an sich sollte das programm ja gehen..vorher war halt alles in einer klasse und jetz hab ich es halt in klassen geschrieben...

da sollte eigentlich nur was mit den konstrukoren falsch sein..


----------



## deleted (31. Jul 2007)

Versuche mal dein Javaprogramm mit dem Argument für die virtuelle Maschine:


```
-Xss50000k
```

zu starten!

also:


```
java -Xss50000k MopsKamInDieKueche
```

Das sollte die Standardgröße jedes Threads auf 50 MB setzen.

Und füge in deinen Code Debugmessages ein.

Vielleicht erreicht er die so irgendwie.

Wenn es mit dieser Einstellung immer noch abstürzt, kannst du praktisch sicher davon ausgehen, dass du eine ungewollte Endlosschleife/Endlosrekursion irgendwo hast...


----------



## deleted (31. Jul 2007)

licht400 hat gesagt.:
			
		

> an sich sollte das programm ja gehen..vorher war halt alles in einer klasse und jetz hab ich es halt in klassen geschrieben...
> 
> da sollte eigentlich nur was mit den konstrukoren falsch sein..



Wenn du es aufgesplittet hast, kann sowas durchaus geschehen.
Ich kenne ja nicht dein Programm und weiß nicht, was es tut.

Wenn es z.B. ein rekursiver Dateisucher ist oder ein rekursicher Webcrawler, kann es durchaus sein, dass durch deine Codeänderung pro rekursivem Aufruf nun mehr Stackplatz benötigt wird, und dass der Fehler daher kommt...


----------



## SlaterB (31. Jul 2007)

soviel Gerede, dabei ist doch meine Theorie schon vom Code bestätigt oder stark unterstützt:



> ```
> public aktionen() throws DocumentException {
> 
> t = new tree(d);
> ...


der Code ist widerspricht sich zwar teilweise
(Konstruktor mit Parameter oder nicht?, a benutzt, bevor es erzeugt wird?)

aber offensichtlich gilt
aktionen -> suchfunction -> aktionen -> suchfunction -> aktionen -> suchfunction -> aktionen -> suchfunction -> aktionen -> suchfunction -> aktionen -> suchfunction -> aktionen -> suchfunction -> aktionen -> suchfunction ->  ...


----------



## licht400 (31. Jul 2007)

daran wird es wohl liegen, aber wie schreib ich den konstruktor da um, bzw so das es nich rekursiv ausgelegt wird?


----------



## SlaterB (31. Jul 2007)

mach dir ein Konzept, wer wen erzeugt,
du wirst doch sicherlich alles nur einmal haben beim Programmstart?

also z.B. erst aktionen und gib das aktionen-Objekt
suchfunction als Parameter mit, so wie du es bei
public suchfunction(tree t)
doch auch schon mit tree machst,


sf = new suchfunction(this,t);


-------

Klassen groß schreiben!


----------



## licht400 (31. Jul 2007)

ja ok..bin zwar grad leich überfordert ..mhh und was gebe ich der main mit, damit ich design aufrufen kann?

ich schreibe mal auf wer auf was zugreift..

die klasse fenster soll auf design zugreifen..
die klasse design auf aktionen..
die klasse aktionen auf tree, design, suchindex..
die klasse tree greift auf design zu..
die klasse suchindex greift auf suchfunktion, design, tree..
die klasse suchfunktion greift auf design, aktionen zu
die klasse auslesen tree, design zu

und eigentlich hab  ich die zufriffe so


----------



## SlaterB (31. Jul 2007)

verstehe ich nicht, ich denke die main erzeugt nur aktionen?


----------



## licht400 (31. Jul 2007)

in der main ..design d = new design(a);

und das haut nicht hin..hab oben noch mal hingeschrieben welche klasse auf welche zugreift


----------



## SlaterB (31. Jul 2007)

aha, eine Rätselaufgabe hier 

fange in der main mit auktion,

Konstruktor auktion macht dann:
- erzeugt sich intern design, übergibt sich selber (this) dabei an design
- in auktion dann als nächstes tree erzeugen und das schon erzeugte design als Parameter übergeben
- dann suchfunktion erzeugen, design + auktion (this) Parameter

als nächstes wird suchfunktion erzeugt,
statt in auktion könntest du nun wieder in der main arbeiten (oder in einer init-Operation),
je nach Geschmacksssache,
im Konstruktor von auktion hättest du die benötigten Parameter (design + auktion) als this oder Exemparvariable vorhanden,
in der main hast du nur auktion, design könntest du aber mit auktion.getDesign() oder ähnlich abfragen

für suchindex, fenster und auslesen ähnlich

---------

andere Variante, die ich mal angedeutet habe: alle Konstruktoren leer,
in der main erzeugst du von allen ein Objekt:
new auktionen();
new design();
...

danach 8x init mit den 8 fertigen Objekten aufrufen:
auktion.init(tree, design, suchindex);
tree.init(design);
...


--------

hier sieht man besonders schön, wie schwierig es nun ist, zu unterscheiden,
ob man da gerade mit Klassen oder mit Objekten der Klasse hantiert,

Klassen groß schreiben!


----------



## licht400 (31. Jul 2007)

ich würde letzteres gerne machen...
ich erzeuge die konsturkoren!

aktionen a = new aktionen();
design d   = new  design();
.
.
etc. (und wo, wenn ich alle aufeinmal erzeugen soll?)

und meinst mit danach, gleich dort wo die leeren konstuktoren stehen?

ich dank dir denoch  schon mal und hoffe das ich dich nich allzu sehr strapaziere...


----------



## SlaterB (31. Jul 2007)

in der main erst die Objekte erzeugen und in 8 Variablen speichern
und dann in der main 8x init aufrufen,

edit: sind wohl 7..


----------



## licht400 (31. Jul 2007)

jap wollt ich grad machen..
hab leere konstuktors gemacht
design d        = new design();  
        aktionen a      = new aktionen();

und dann wollt ich

a.init --> aber init gibts nicht
aktionen.init -->init gibts hier auch nicht..

und ich bin in der main!


----------



## SlaterB (31. Jul 2007)

von selber passiert das nicht, musst dir schon entsprechende Operationen definieren


----------



## licht400 (31. Jul 2007)

ja das konnt ich mir denken und was soll das init machen?
die soll ja, dem konstuktor sagen, mit wem es bekannt gemacht werden soll..aber irgendwie weiß ich nicht wie!


----------



## SlaterB (31. Jul 2007)

..


```
public class aktionen { 

    private design d; 
    private tree t; 
    private suchindex si; 
    private suchfunction sf; 

       public aktionen() throws DocumentException { 
        d = new design(); 
        t = new tree(); 
        si= new suchindex(); 
        sf= new suchfunction(); 
        
    } 
}
```


```
public class aktionen { 

    private design d; 
    private tree t; 
    private suchindex si; 
    private suchfunction sf; 

       public aktionen() { 
       }

    public void init(design d, tree t, ..) {
        this.d = d; 
        this.t = t; 
        ....        
    } 
}
```


----------



## licht400 (31. Jul 2007)

ja danke, aber du hast vorhins geschrieben das sollte alles in die main, jetz schreibst das ja in die klasse!


----------



## SlaterB (31. Jul 2007)

in der main steht nur der Aufruf,
autionen a = new autionen();
....

a.init(d,t,...);



die Operation init (wie ALLE Operationen einer Klasse) steht in der Klasse selber?


----------



## licht400 (31. Jul 2007)

k, danke, werd mich dran setzen und es hinbekommen 
denk ich jedenfalls bis jetz


----------



## licht400 (31. Jul 2007)

danke, das dürfte geklappt haben..

also es hat alles schon mal funktioniert, wollt es halt nur in klassen machen..

ein jtree füllen..klappt..

Jtree = new Jtree(intro); -->intro steht was drin
d.menupanel.add(tree, BorderLayout.Center);(-->d --> design wo menupanel drin ist)
tree.addTreeSelectionListener(this.a); --> a- aktion, wo listener ist

problem..beim adden bringt er ein nullpointer obwohl im tree was drin steht..merkwürdig!


----------



## licht400 (31. Jul 2007)

wieso ist tree leer obwohl was drin steht..versteh ich nicht..
wenn in intro was drin steht(tut es zu 100%iger sicherheit)
muss doch in tree auch was drin stehen..jedes mal nullpointer


----------



## SlaterB (31. Jul 2007)

poste ein vollständiges Beispielprogramm..


----------



## licht400 (31. Jul 2007)

```
//XML - read in
        SAXReader reader = new SAXReader();
        Document doc = reader.read("menu.xml");
        Element used = doc.getRootElement();
        DefaultMutableTreeNode intro = new DefaultMutableTreeNode(used.getName());
        appendChilds(used, intro);
        //System.out.println(used +","+ intro);
        tree = new JTree(intro); 
        System.out.println(intro);
        d.menuPanel.add(tree,BorderLayout.CENTER);
        tree.addTreeSelectionListener(a);
```


das hatte ja auch schon funktioniert wo noch alles in einem war 

..es wird aus einer xml ausgelesen und in used bzw intro gespeichert. da steht auch was drin, hab ich nachgeschaut.
dann übergebe ich den inhalt intro an tree weiter..dann möchte ich, dass er das Tree(mit dem inhalt) auf dem MenuPanel legt..
aber da gibt er mir eine nullpointer...obwohl im was drinen stehen sollte, es aber nicht tut.

edit 1: das d kommt vom design und das a kommt von aktionen da da der listener ist
edit 2:
und in design ist das..

```
splitPane = new JSplitPane();
        splitPane.setResizeWeight(0.08);
        this.getContentPane().add(splitPane, BorderLayout.CENTER);
        
        // Panel left
        menuPanel = new JPanel();
        menuPanel.setLayout(new BorderLayout());
        splitPane.setLeftComponent(menuPanel);
```


----------



## SlaterB (31. Jul 2007)

mach doch mal
tree = new JTree(); 
oder irgendein anderen BeispielTree ohne XML,
funktioniert doch sicher damit genauso nicht,

a ist null oder d ist null oder menuPanel ist null usw,
alles getestet?

edit: wer auf der Welt braucht ein Splitpane?
 entfernen und JTree so einfügen,

erst wenn das einfache funktioniert, DANN vielleicht mit Splitpane verschönern


----------



## licht400 (31. Jul 2007)

ja das ding ist ja, dass so wie funktional ist, ja schon funktioniert hat, nur nicht in verschiedenen klassen...
hab tree mal leer gelassen, da bringt bei d.menuPanel etc immer noch nullponiter..
das liegt an dem tree, warum auch immer 
(kann doch net sein, verflucht nochmal  )

edit: und wenn ich das d.menuPanel.add(tree, BorderLayout.CENTER) rausnehme, dann startet das programm auch, aber er zeigt mir halt kein jtree menu an..


----------



## SlaterB (31. Jul 2007)

na wenn du meinst das alles geht, umso besser, nix mehr zu tun 




```
public class TestGUI
    extends JFrame
    implements TreeSelectionListener
{

    public TestGUI()
        throws Exception
    {
        JTree tree = new JTree();
        JPanel p = new JPanel();
        p.add(tree);
        tree.addTreeSelectionListener(this);
        getContentPane().add(p);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 400);
        setVisible(true);
    }


    public void valueChanged(TreeSelectionEvent e)
    {
    }

    public static void main(String[] args)
        throws Exception
    {
        new TestGUI();
    }
}
```
läuft jedenfalls


----------



## licht400 (31. Jul 2007)

ich habs ja so wie du..bloß das mein panel in design ist und mein jtree in auslesen..

da vermut ich mal, das es an dem d.menuPanel.add(tree,BorderLayout.CENTER);   d liegt...

wenn ich die komplette zeile auskommentiere, geht es, halt ohne das jtree(aber nicht sinn ;-) )


----------



## SlaterB (31. Jul 2007)

deshalb wie gesagt: 


			
				SlaterB hat gesagt.:
			
		

> poste ein vollständiges Beispielprogramm..



und XML kannst du rauslassen, ein einfacher new JTree() tuts genauso


----------



## licht400 (31. Jul 2007)

hier die klassen
fenster is main
auslesen ist jtree vorhanden
design ist menupanel drin

und bei   d.menuPanel.add(tree,BorderLayout.CENTER); kommt nullpointer



```
public class fenster {
    public static void main(String[] args) throws Exception {
        aktionen a      = new aktionen();
        design d        = new design(); 
        auslesen au     = new auslesen();
        suchfunction sf = new suchfunction();
        suchindex si    = new suchindex();
        tree t          = new tree();
        
        
        d.init(a);
        a.init(d,t,si,sf);
        au.init(d,a);
        sf.init(d,a);
        si.init(sf,d);
        t.init(d);
        
        d.setSize(800, 600);
        d.setLocation(250, 200);
        d.setResizable(false);
        d.setBackground(Color.WHITE);
        d.setTitle("Version 0.1");
        d.setVisible(true);
        
    }

}
```


```
public class auslesen {
     
    JTree tree;
    
    private design d;
    private aktionen a;
   
   public void init(design d, aktionen a){
        this.d=d;
        this.a=a;
    }
    /** Creates a new instance of auslesen */
    public auslesen() throws DocumentException {
     
         //XML - read in
       // SAXReader reader = new SAXReader();
        //Document doc = reader.read("menu.xml");
        //Element used = doc.getRootElement();
        //DefaultMutableTreeNode intro = new DefaultMutableTreeNode(used.getName());
        //appendChilds(used, intro);
        //System.out.println(used +","+ intro);
        tree = new JTree();
        //System.out.println(intro);
        d.menuPanel.add(tree,BorderLayout.CENTER);
        tree.addTreeSelectionListener(a);
```
    }


```
public void init(aktionen a){
        this.a=a;
        
    }
    
    public design(){
           
        splitPane = new JSplitPane();
        splitPane.setResizeWeight(0.08);
        getContentPane().add(splitPane, BorderLayout.CENTER);
        
        
        // Panel left
        menuPanel = new JPanel();
        menuPanel.setLayout(new BorderLayout());
        splitPane.setLeftComponent(menuPanel);
        
        // Panel right
        contentPanel = new JPanel();
        contentPanel.setLayout(new BorderLayout());
        contentPanel.setBackground(Color.WHITE);
        splitPane.setRightComponent(contentPanel);
```


----------



## SlaterB (31. Jul 2007)

??
habe ich nicht gesagt, dass du erst prüfen sollst, ob nicht a oder d oder d.mainPanel null ist?
hast du nicht einen Millimeter selber gesucht, z.B. mit

```
tree = new JTree(); 
//System.out.println(intro); 
if (d == null) {
  System.out.println("das kann ja gar nicht gehen, d ist hier null");
}
d.menuPanel.add(tree,BorderLayout.CENTER);
```
wieso prüfst du intro, aber nicht d?
denn d ist hier null, wird doch erst später in init() gesetzt..

so, ich bin nun langsam mit meiner Zeit am Ende,
falls du noch mehr solcher Kaliber hast, überlege dir genau, was du fragst und wieviel Eigenleistung du vorher reinsteckst,
ich zumindest werde hier nicht ewig antworten (vielleicht ja andere)


----------



## licht400 (31. Jul 2007)

ich sag ja die ganze zeit das es an d liegt..aber d sollte doch garnicht mehr null sein, das versteh ich nicht!


----------



## SlaterB (31. Jul 2007)

> ich sag ja die ganze zeit das es an d liegt
+ vorher
> das liegt an dem tree, warum auch immer
...

----------

erläre doch mal deine Gedanken,
warum denkst du, dass d zu diesem Zeitpunkt nicht null ist?
und überlege dir, in welche Zeile die main-Operation zu diesem Zeitpunkt (d.menuPanel.add(tree,BorderLayout.CENTER); ) ist


----------



## licht400 (31. Jul 2007)

d "sollte" zu diesem zeitpunkt nicht null sein, ist es aber.

weil design doch schon initialsiert sein muss und somit nicht null ist oder?

wenn der (d.menuPanel.add(tree,BorderLayout.CENTER) hier ist, dann is er in der main bei auslesen au     = new auslesen();

ach und da kennt er das d noch nicht oder? mhh aber wie geb ich im das den mit..wenn der noch nicht bei der init war?


----------



## SlaterB (31. Jul 2007)

eine logische Folge wäre, wie anfangs gesagt, den Konstruktor LEER zu lassen (GANZ GANZ DOLL LEER),
und den restlichen Code auch in die init-Operationen zu verschieben,

hier musst du aber so oder so auf Reihenfolge achten,
erst in der GUI-Klasse init() aufrufen, damit dort die Panels erstellt werden, erst dann die Tree-Klasse arbeiten lassen


----------



## licht400 (31. Jul 2007)

danke, ich versuch es weiter..
das ist mir gerade zu hoch!
eigentlich ist der konstruktor doch gan ganz leer 
design d        = new design(); 

na ich lass es für heute...steh da wohl mit beiden beinen auf dem schlauch!


----------



## SlaterB (31. Jul 2007)

nicht leer im Sinne von keine Parameter, sondern leer im Sinne von kein Inhalt

public design() {

}

statt 
public design() {
// jede Menge Code
}


andererseits ist in design ja auch nix gefährliches im Konstruktor drin, 
da wäre es schon günstig, die Panels sofort im Konstruktor zu erstellen,

nur in den Klassen, in denen im Konstruktor auf die berümten 7 Hauptobjekte zugriffen wird,
sollte diese Zugriffe (wie d.menuPanel.add(tree,BorderLayout.CENTER);  zweifellos einer ist)
erst in init() ausgeführt werden, da erst in init() diese 7 Opjekte überhaupt zur Verfügung stehen..

eigentlich ganz einfach


----------



## licht400 (31. Jul 2007)

ist das sinn und zweck, dass der quellcode jetz in der init steht und 
die die klasse auslesen leer ist?


danke für deine langanhaltende ausdauer


----------



## SlaterB (31. Jul 2007)

nur der Konstruktor, da erst alle Objekte im Objektkreis erzeugt und ausgetauscht werden müssen,
und wie gesagt wäre es am besten, wenn der Konstruktor doch nciht ganz leer ist sondern z.B. die JPanel (die nicht von den anderen Klassen abhängen) dort schon initialisiert werden

je nachdem, wie verzahnt die Objekte aufeinander zugreifen muss auch die init()-Variante nicht immer helfen,
manchmal muss man einfach auf eine richtige Reihenfolge achten,
ist ja ganz normal, dass man erst JPanel x erzeugt, bevor man y in x einfügt,
deswegen stand ja die durchdachte Reihenfolge der Initialisierung von Anfang an auch zur Wahl,


----------



## Cobrus (6. Jan 2008)

Hallo, bei mir ergibt sich auch ein StackOverflowError. Ich vermute, dass ich mir irgendwie eine Endlosausführung gebastelt habe, weiß aber nicht wie und wo.


```
public static void rekursion (double betrag, int laufzeit) {
//Eingabe kommt aus der main als (betrag, 1)
    
    betrag = betrag / 1.1;
    laufzeit++;
    
    if (betrag == 1)
      System.out.println(laufzeit);
    else
      rekursion(betrag, laufzeit);
         
  }
```

Gruß,
Cobrus


----------



## Cobrus (6. Jan 2008)

Hmm, ich habe das Problem gelöst. Habe allerdings keine genaue Ahnung wieso. Kann mir evtl. jemand erklären, warum die Änderung besser ist?


```
public static void rekursion (double betrag, int laufzeit) {
    
    if (betrag <= 1) {
      double laufzeitJahr = Math.round(laufzeit / 365.0 * 10) / 10.0;
      boolean b;
      if (laufzeit == 1)
        b = true;
      else
        b = false;
      JOptionPane.showMessageDialog(null,"Das Ansparen dauerte " + laufzeit + " Tag" + (b ? "" : "e bzw. " + laufzeitJahr + " Jahre") + ".");
    }
    else {
      betrag = Math.round((betrag / 1.1) * 100) / 100.0;
      laufzeit++;
      rekursion(betrag, laufzeit);
    }
```

Gruß,
Cobrus


----------



## Marco13 (6. Jan 2008)

Hab die neue Lösung jetzt nicht nachvollzogen, aber eine abfrage

```
if (floatWert == 1.234f)
```
ist immer Problematisch: Float werte werden fast nie genau dargestellt, und eine Abfrage mit == schlägt oft fehl. In diesem Fall sollte der Vergleich wohl eher lauten

```
if (Math.abs(betrag-1.0f) < 1e-4)
```


----------



## Guest (7. Jan 2008)

Ah, ich verstehe, was Du meinst. Dankeschön.


----------

