# Variable einer Methode in anderer Methode aufrufen



## Dragsteal (17. Okt 2008)

Hi, 
bin neu hier im Forum und habe mich nach schier endloser Suche
dazu durchgerungen hier nachzufragen.

Mein Problem:
Ich habe in einer Methode eine String Variable _text_ deklariert und ihr 
natürlich auch einen "Wert" zugewiesen.
Nun möchte ich genau diese Variable in einer anderen Methode derselben
Klasse wieder aufrufen.
Es soll aber keine extra Klasse dafür angelegt werden, das sei schon einmal vorweg gesagt.

Meine Frage:
Ist das so bei Java überhaupt möglich und wenn ja wie genau funktioniert das?


MfG

Dragsteal


----------



## AmunRa (17. Okt 2008)

Du könntest den String als Klassenvriable abspeichern 

dann ist er in jeder Methode sichtbar


----------



## Dragsteal (17. Okt 2008)

Ich poste hier am besten doch nochmal meinen code damit das ganze besser zu sehen ist.


```
import java.io.*;
import java.net.*;

public class HTTPServer implements Runnable{

	ServerSocket server = new ServerSocket(1100);

	public HTTPServer() throws IOException{
		while (true){
			Socket client = server.accept();
			DataInputStream input = new DataInputStream(client.getInputStream());
			DataOutputStream output = new DataOutputStream(client.getOutputStream());
			output.writeUTF(text);    //hierhin soll die Variable text übergeben werden
			output.flush();
			input.close();
			output.close();
		}
	}

	public static void main(String[] args){
		try{
			HTTPServer server = new HTTPServer();
		}
		catch(IOException e){
			System.out.println(e);
		}
	}

	public void run() {
		for(int i=10; i<=60; i+=10){
			try{
				Thread.sleep(10000);
			}
			catch(InterruptedException e){
			}
			String text="Zeit in Warteschleife: "+i+ " Sekunden";     //die Variable text wird erst hier definiert
		}
	}
}
```


Das Problem bei deiner möglichkeit ist, dass ich nicht wirklich weiß wie ich dann
die Klassenvariable verändern kann, damit diese Veränderung auch in der anderen Methode
sichtbar wird.


----------



## AmunRa (17. Okt 2008)

```
import java.io.*; 
import java.net.*; 

public class HTTPServer implements Runnable{ 

   ServerSocket server = new ServerSocket(1100); 

  private String text="";  // <==== nun kannst du in allen Methoden darauf zugreifen

   public HTTPServer() throws IOException{ 
      while (true){ 
         Socket client = server.accept(); 
         DataInputStream input = new DataInputStream(client.getInputStream()); 
         DataOutputStream output = new DataOutputStream(client.getOutputStream()); 
         output.writeUTF(text);    //hierhin soll die Variable text übergeben werden 
         output.flush(); 
         input.close(); 
         output.close(); 
      } 
   } 

   public static void main(String[] args){ 
      try{ 
         HTTPServer server = new HTTPServer(); 
      } 
      catch(IOException e){ 
         System.out.println(e); 
      } 
   } 

   public void run() { 
      for(int i=10; i<=60; i+=10){ 
         try{ 
            Thread.sleep(10000); 
         } 
         catch(InterruptedException e){ 
         } 
          text="Zeit in Warteschleife: "+i+ " Sekunden";     //hier wird der Text dann zugewiesen
      } 
   } 
}
```


----------



## Landei (17. Okt 2008)

OMG!

In deinem Code ist so ziemlich alles daneben:
1)Die Methode run() zu definieren reicht nicht, es muss auch irgendwo einem Thread übergeben werden. Probiere einfach mal ein System.our.println() in run(), dann wirst du sehen, dass das gar nicht läuft. Also brauchst du irgendwo ein new Thread(this).start(); Allerdings solltest du dir mal java.util.TimerTask anschauen, der ist wahrscheinlich geeigneter.

2) Woher soll denn dein Konstruktor wissen, wann da noch etwas kommt oder wann er sich (und die Streams) schließen soll? Die ganze Logik ist verquer. Eine Möglichkeit wäre, alles (bis auf den Thread-Start) in deine run()-Methode zu packen, nach dem Schema (mal als Pseudocode):


```
public HTTPServer()  {
  new Thread(this).start();
}

public void run() {
  //Streams und so inititalisieren
  //Schleife ausführen und Text in den Stream schreiben
  //Streams schließen
}

public static void main(String[] args) throws Exception{ 
  new HTTPServer();
}
```


----------



## Dragsteal (17. Okt 2008)

@:Amun RA

Leider funktioniert das so nur nicht.
_text_ ist nun zwar für alle Methoden verfügbar, jedoch
wird der in Zeile 39 übergebene Wert nicht für alle
anderen Methoden übernommen. 
Und genau das ist ja mein Problem.


----------



## SlaterB (17. Okt 2008)

doch, oder poste ein Quellcode mit Bedienungsanleitung zur Ausführungen
und Erklärung, was darin nicht funktioniert


----------



## AmunRa (17. Okt 2008)

Ich nimm an das wirklich nur der fehlende Start des Threads schuld am Problem ist


----------



## Landei (17. Okt 2008)

ABER ES IST DOCH NICHTS IM KONSTRUKTOR, DAS SAGT: "WARTE DOCH BITTE MAL, BIS DER THREAD EIN ERGEBNIS LIEFERT!" 

Ob die Text-Variable gefüllt ist oder nicht, bevor sie gelesen wird, ist Glückssache. Und dann liest du sie genau EINMAL aus, und überträgst EINMAL Daten in deinem Stream.


----------



## Dragsteal (17. Okt 2008)

Im großen und ganzen soll das Programm so funktionieren,
dass mehrere Clients eine Anfrage an den Server stellen und
der sie dann für 60 Sekunden in eine Warteschleife packt.
Zusätzlich soll er jedem Client alle 10 Sekunden sagen, wie 
lange dieser Client schon wartet.
Die Clients sollen aber natürlich alle zu einer unterschiedlichen
Zeit die Anfrage stellen können und sollen dann auch natürlich
die richtige Wartezeit zurückbekommen.

Ich hatte es bisher nur hinbekommen, dass die Clients nacheinander
abgearbeitet werden.
Mir wurde gesagt das Problem könnte ich mit Threads lösen.
Der Ursprungscode sieht folgendermaßen aus:


```
import java.io.*;
import java.net.*;

public class HTTPServer{

	ServerSocket server = new ServerSocket(1100);

	public HTTPServer() throws IOException{
		while (true){
			Socket client = server.accept();
			DataInputStream input = new DataInputStream(client.getInputStream());
			DataOutputStream output = new DataOutputStream(client.getOutputStream());
			for(int i=10; i<=60; i+=10){
				try{
					Thread.sleep(10000);
				}
				catch(InterruptedException e){
				}
				output.writeUTF("Zeit in Warteschleife: "+i+ " Sekunden");
			}
			output.flush();
			input.close();
			output.close();
		}
	}

	public static void main(String[] args){
		try{
			HTTPServer server = new HTTPServer();
		}
		catch(IOException e){
			System.out.println(e);
		}
	}
}
```


----------



## Schandro (17. Okt 2008)

> text ist nun zwar für alle Methoden verfügbar, jedoch
> wird der in Zeile 39 übergebene Wert nicht für alle
> anderen Methoden übernommen.



Warum baust du nicht ein paar Sytem.out.println() ein und guckst, ob:
text="Zeit in Warteschleife: "+i+ " Sekunden";
überhaupt aufgerufen wird?

Is nur en Tipp für die Zukunft, die anderen ham schließlich schon die Lösung gesagt...


----------



## Dragsteal (17. Okt 2008)

wenn ich nun die Streams in dir run-Methode packe meckert er rum, dass
die IOException nicht erkannt wird. Wenn ich dies dann mit

```
public void run()throws IOException
```
hinzufüge meckert er weiter oben rum, das dies nicht ginge
weil ich oben Runnable implementiere.

Was mache ich falsch?
Oder brauch ich Runnable nicht?


----------



## Landei (17. Okt 2008)

Wenn du ein Interface implementierst, musst du dich an die vorgegebenen Definitionen der Methoden halten, d.h. du kannst nicht einfach Exceptions hinzufügen.

In diesem Beispiel ist das throws sowieso ziemlich zweckfrei: Wer soll deiner Meinung nach die Exception abfangen? Schließlich wird der Code in einem anderen Thread ausgeführt, und dieser Thread weiß bestimmt nicht, wie du auf eine IOException reagieren willst. Kurz gesagt: run() muss sich selber um das Problem kümmern (natürlich kann run() es auch irgendwie "weitermelden", aber eben nicht über den normalen Exception-Mechanismus). 

Die Kern-Frage ist also: Was soll passieren, wenn eine IOException auftritt, und das kannst nur du selber wissen...


----------



## Dragsteal (17. Okt 2008)

Ok das mit der Exception hab ich nun hinbekommen.

Nun ist aber das Problem, dass nur ein Client abgearbeitet wird und ein
weiterer nicht.

Was müsste ich denn genau verändern, damit beliebig viele Clients, genau zu
deren Anfragezeitpunkt bearbeitet werden? (basierend auf den letzten "großen"
Code den ich gepostet habe)


----------



## Dragsteal (30. Okt 2008)

Hi,
ich bins mal wieder. Meine Frage wurde ja nicht ganz so zu meiner Zufriedenheit geklärt. (Wir sind da nämlich ein wenig
vom Thema abgekommen, was aber nicht schlimm ist, da ich das Problem dann doch noch erfolgreich lösen konnte^^)

Allerdings würde ich trotzdem nochmal gerne auf die Ursprungsfrage zurückkehren.

genaue Frage:
Wie kann ich eine Variable in *Methode A* definieren und dann in *Methode B* aufrufen? (allgemein)
(Die Antwort ist zwar sicherlich einfach, aber ich hab noch keine Lösung gefunden. :bahnhof: )

Falls das mit getter und setter gehn soll, kann mir das denn genau erklären (oder nen guten Link dazu geben?),
denn irgendwie versteh ich das nicht richtig.^^

MfG
Dragsteal


----------



## Dragsteal (31. Okt 2008)

nagut, wenn ihr das Thema schon für euch geschlossen habt, dannn werd ich mich wohl weiter
umschaun müssen :###, da ich dafür nicht extra ein neues thema erstellen möchte.  :? 

mfg
Dragsteal


----------



## SlaterB (31. Okt 2008)

da gibts nicht viel zu sagen,
du brauchst ein Klassenattribut so wie

> ServerSocket server

in deinem Posting von "Verfasst am: 17. 10. 2008, 9:58 "

und dann kannst du in allen Methoden darauf zugreifen, entweder direkt oder per setter/ getter,
fertig

definiert wird das dann nicht in Methode A sondern direkt in der Klasse,
in A wird der Variablen vielleicht etwas zugewiesen


----------



## Dragsteal (31. Okt 2008)

Ich poste hier am besten nochmal den Code, ich denke dann wird vielleicht besser ersichtlich was ich
genau vorhabe.^^


```
import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Chatclient extends JFrame {

//-----------------------------------------------
  
  Socket client = new Socket();
  Socket server;
  private String ip;     //hier wird die Variable ip deklariert
  
  JFrame      window      = new JFrame("Login");
  JTextField  nickField   = new JTextField();
  JTextField  ipField     = new JTextField();
  JLabel      nickLabel   = new JLabel("Nickname:");
  JLabel      ipLabel     = new JLabel("Server-IP:");
  JButton     loginButton = new JButton("Login");    
  JTextField  inputfield  = new JTextField();
  JTextArea   outputarea  = new JTextArea();
  
//-----------------------------------------------
  
  public Chatclient(){
      init();
      System.out.println(ip);      //hier sollte ip testweise mal ausgegeben werden um zu schauen, ob alles klappt
      try{
        server = new Socket(ip,80);      //und hier soll ip letzten endes rein!
      }
      catch(IOException e){        
      }
  }
    
//-----------------------------------------------
  
  public void init(){    
    window.setSize(200, 125);
    window.setResizable(false);
    window.setLocationRelativeTo(null);
    window.getContentPane().setLayout(new BoxLayout(window.getContentPane(), BoxLayout.Y_AXIS));
    window.getContentPane().add(nickLabel);
    window.getContentPane().add(nickField);
    window.getContentPane().add(ipLabel);
    window.getContentPane().add(ipField);
    window.getContentPane().add(loginButton);
    window.setVisible(true);
    loginButton.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        loginEvent(e);
      }
    });    
  }
  
//-----------------------------------------------
  
   void loginEvent(ActionEvent e){
    window.remove(loginButton);
    window.remove(nickLabel);
    window.remove(ipLabel);
    window.remove(nickField);
    window.remove(ipField);
    
    window.setTitle("LAN-Chat");
    window.setSize(600, 400);
    window.setLocationRelativeTo(null);
    window.getContentPane().setLayout(new BorderLayout());
    window.getContentPane().add("South", inputfield);
    window.getContentPane().add("Center", outputarea);
    outputarea.setEditable(false);
    window.setVisible(true);
    
    ip = ipField.getText();      //hier wird der Variable erst der Wert zugewiesen
  }
   
//-----------------------------------------------  
  
  public boolean handleEvent(Event evt){
    if(evt.id==Event.WINDOW_DESTROY)
      System.exit(0);
    return false;
  }
  
//-----------------------------------------------
  
  public static void main(String[] args){
    try{
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(Exception e){      
    }
    new Chatclient();
  }
}
```

Wie du vielleicht sehen dürftest, wird der Variable (hier ip) in einer Methode (Beispiel war A) der Wert zugewiesen,
aber in einer anderen Methode (Beispiel war B) wird dieser Wert erst gebraucht.

EDIT:
Bitte nicht über das eventuelle Chaos bzw. die umständlichen Methoden im Code wundern, ist erstma nur
übergangsweise. Wichtig ist erstma, dass alles klappt, aufgeräumt wird später!  :wink:


----------



## SlaterB (31. Okt 2008)

das Programm kompiliert doch, was ist deine Frage? immer genau alles erklären,

aber so wie es da steht macht das keinen Sinn:
der Konstruktor ChatClient wird direkt beim Erzeugen des Objektes ausgeführt, wann sonst?
also wird nach 5 Nanosekunden bereits auf ip zugegriffen,

ip wird aber erst durch einen Login-Button gesetzt, also potentiell erst 10 Sekunden später,
dann nützt es doch nicht mehr, dass sich der Wert von ip ändert..

du solltest den Code von Zeile 29-34 vielleicht nach Zeile 76 verschieben,


----------



## Dragsteal (31. Okt 2008)

ok...darauf hät ich auch kommen können xD
Danke auf jeden Fall, das hat mir erstma sehr weitergeholfen^^
aber ich denke, ich sollte mir die sache mit den gettern und settern trotzdem mal anschauen,
schadet ja nie sowas zu wissen. 

mfg
Dragsteal


----------

