# Problem mit return-werten



## Man-in-Black (23. Jan 2009)

So der Titel is vielleicht irreführend aber was besser is mir grad net eingefallen 

ich hab folgendes Problem:

Ich schreibe gerade an meiner Bachelorarbeit und habe im Zuge dessen einen TCP-Server entwickelt, der Anfragen entgegennimmt und mir dann eben Antworten schickt.

Nun hab ich aber ein kleines Problem bei dem mir selbst meine Kommilitonen net helfen konnten.

Ich habe eine Server-Klasse, in der die ganzen Funktionen definiert sind (wär hätts gedacht )

Nun habe ich eine JList in meiner grafischen Oberfläche, die bei Klick die UserListe der verbundenen User auf dem Server neu abrufen soll.
Die User werden in einer Hashtable gespeichert.

Hier mal der Teil der die verbundenen User abfragt:


```
public String getUsers() {
   String users;
   users="users|";
   for (Enumeration e = clients.keys();e.hasMoreElements();)
      users+=(String) e.nextElement() + "|";
   if (! users.equals("users|"))
      users = users.substring(0, users.length() - 1);
   return users;
}
```

Innerhalb der Serverklasse funktioniert das abrufen der verbundenen User tadellos.

Nun habe ich für die grafische Oberfläche aber eine neue Klasse angelegt, in der die User dann eben dargestellt werden.
Dafür verwende ich eine JList. Der Aufbau der Oberfläche ist hier aber recht egal.

Allerdings nicht die Übergabe der verbundenen User, die funktioniert nämlich nicht.

Ich habe ganz rudimentär bei klick eines Buttons veranlasst, die Liste neu einzulesen, und er schreibt auch schön darunter, aber eben nur den String "users|", alle anderen verbundenen User eben nicht.

```
class UpdateListener implements ActionListener {
   public void actionPerformed(ActionEvent f) {
      listModel.addElement(server.getUsers());
   }
}
```

Ich hoffe ihr könnt mir helfen bei meinem Problem, da das gerade irgendwie der Knackpunkt ist.

Beim debuggen sieht das ganze so aus, wie wenn die Hashtable für die GUI-Klasse einfach leer ist.

Solltet ihr noch irgendwelche weiteren Codeschnipsel brauchen oder weitere Infos die ich jetzt vergessen habe sagt einfach Bescheid, die liefer ich dann direkt nach.

Ich danke euch jetzt schon mal für die Mithilfe

Gruß
Man-in-Black


----------



## hdi (23. Jan 2009)

also mit Klassen-übergreifenden return-Werten hat das nichts zu tun, sowas gibt keine Probleme.
Eigentlich kommen nur 2 Dinge in Frage:

1) Das Objekt "server" im Client ist nicht wirklich das gleiche Server-Objekt, wie das, in dessen HashMap
du alle clients speicherst

2) Irgendwas stimmt nicht mit dem Updaten der HashMap bei neuen Clients, sodass das evlt hinterherhinkt..

Lass dir bitte erstmal nur den Aufruf


```
server.getUsers();
```

bei deinem Button-Listener auf der Konsole ausgeben, damit man ausschliessen kann, dass es sich nur
um einen grafischen Fehler/internen Model-Fehler deiner JList handelt.


----------



## Man-in-Black (23. Jan 2009)

also habe nun auch mal einfach ausgeben lassen auf der konsole da steht auch nur das berüchtige "users|", genau wie in der liste, damit kann es also nix zu tun haben.

im debugger ist die hashliste bei dem aufruf aus der anderen funktion auch leer.

und in der gui-klasse greife ich über ein objekt des servers auf die funktion zu, sollte also auch passen. gestartet ist der server natürlich auch, das geschieht direkt beim start des programms.

ich denke eher dass fall 1 zutrifft, aber wie kann ich das herausfinden und viel wichtiger, wie kann ich das beheben?


----------



## hdi (23. Jan 2009)

Um das beantworten zu können brauchen wir den kompletten Code + main Methode
(zumindest alles was damit zu tun hat)


----------



## Gelöschtes Mitglied 5909 (23. Jan 2009)

verwendest du RMI oder ein eigenes Protokoll? irgendwo müssen die Daten ja herkommen und ich befürchte dass da was schief geht


----------



## Man-in-Black (23. Jan 2009)

ok dann poste ich mal (wenns net ganz so schön formatiert is sorry aber ich will net jede zeile bearbeiten nu )

*Server:*

```
public class Server {

   private Hashtable clients;
   private int port;

   public Server(int port) {
      this.port=port;
      clients = new Hashtable();
   }

   private void startServerListener() {
      ServerSocket ss ;
      try {
         ss = new ServerSocket(port);
         System.out.println("Server gestartet...");
         while (true)
            new ServerBody(ss.accept(), this).start();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }

   public void addClient(String name, ServerBody body) {
      clients.put(name, body);
   }

   [...]

   public String getUsers() {
      String users;
      users="users|";
      for (Enumeration e = clients.keys();e.hasMoreElements();)
         users+=(String) e.nextElement() + "|";
      if (! users.equals("users|"))
         users = users.substring(0, users.length() - 1);
      return users;
   }

   public void broadcast(String name, String msg) throws Exception {
      for (Enumeration e = clients.keys();e.hasMoreElements();)
         ((ServerBody) clients.get((String) e.nextElement())).send(name+ ": " + msg);
   }

   public void send(String name, String targetname, String msg) throws Exception {
      ((ServerBody) clients.get(targetname)).send(/*name+ ": " + */msg);
   }

   public boolean isClient(String name) {
      return clients.containsKey(name);
   }

   public static void ServerStart(String[] x) {
      if (x.length != 1) {
         System.out.println("#java Server <port>");
         System.exit(0);
      }
      new Server(Integer.parseInt(x[0])).startServerListener();
   }
}

class ServerBody extends Thread {

   private Socket cs;
   private Server server;
   private PrintWriter out;

   public ServerBody(Socket cs, Server server) {
      this.cs=cs;
      this.server=server;
   }

   public void run() {
      BufferedReader in;
      StringTokenizer str;
      String command, name, names = null, msg, targetname;
      int n;
      try {
         in = new BufferedReader (new InputStreamReader(cs.getInputStream()));
         out = new PrintWriter(new DataOutputStream(cs.getOutputStream()));
         name = in.readLine();
         server.addClient(name, this);
         //server.broadcast(name, server.getUsers());
         System.out.println("+ Anmeldung Client " + name);
         System.out.println(server.getUsers());
         for (String buffer;(buffer = in.readLine()) != null;) {
            n = buffer.indexOf(" ", 0);
            targetname = buffer.substring(0, n);
            msg = buffer.substring(n + 1, buffer.length());
            if (targetname.equals("all")) {
               server.broadcast(name, msg);
               System.out.println(">Broadcast von Client " + name + " : " + msg);
            } else if (server.isClient(name)) {
               server.send(name, targetname, msg);
               System.out.println(">Nachricht von Client " + name + " an " + targetname + ": " + msg);
            } else
               this.send("Error: Client " + targetname + " existiert nicht!");
         }
         server.removeClient(name);
         System.out.println("- Abmeldung Client " + name + "!");
         System.out.println(server.getUsers());
         in.close();
         out.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   
   }

   public void send(String msg) throws Exception {
      out.println(msg);
      out.flush();
   }
}
```

*GUI*

```
public class Main extends JPanel
                      implements ListSelectionListener {
    private JList list;
    private DefaultListModel listModel;
    Server server = new Server(8080);

    private static final String hireString = "Hire";
    private static final String fireString = "Fire";
    private static final String updateString = "Update";
    private JButton fireButton;
    private JTextField employeeName;
    private JButton updateButton;

//    public void showUsers() {
//        new Thread() {

//            @Override
//            public void run() {
//
//            }
//        }.start();
//    }

    public Main() {

        super(new BorderLayout());
        
        listModel = new DefaultListModel();

        listModel.addElement(server.getUsers());
        
        //Create the list and put it in a scroll pane.
        list = new JList(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setSelectedIndex(0);
        list.addListSelectionListener(this);
        list.setVisibleRowCount(10);
        JScrollPane listScrollPane = new JScrollPane(list);

        JButton hireButton = new JButton(hireString);
        HireListener hireListener = new HireListener(hireButton);
        hireButton.setActionCommand(hireString);
        hireButton.addActionListener(hireListener);
        hireButton.setEnabled(false);

        fireButton = new JButton(fireString);
        fireButton.setActionCommand(fireString);
        fireButton.addActionListener(new FireListener());

        updateButton = new JButton(updateString);
        updateButton.setActionCommand(updateString);
        updateButton.addActionListener(new UpdateListener());

        employeeName = new JTextField(10);
        employeeName.addActionListener(hireListener);
        employeeName.getDocument().addDocumentListener(hireListener);
        String name = listModel.getElementAt(
                              list.getSelectedIndex()).toString();

        //Create a panel that uses BoxLayout.
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new BoxLayout(buttonPane,
                                           BoxLayout.LINE_AXIS));
        buttonPane.add(fireButton);
        buttonPane.add(Box.createHorizontalStrut(5));
        buttonPane.add(new JSeparator(SwingConstants.VERTICAL));
        buttonPane.add(Box.createHorizontalStrut(5));
        buttonPane.add(employeeName);
        buttonPane.add(hireButton);
        buttonPane.add(updateButton);
        buttonPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

        add(listScrollPane, BorderLayout.CENTER);
        add(buttonPane, BorderLayout.PAGE_END);
    }

    class UpdateListener implements ActionListener {
        public void actionPerformed(ActionEvent f) {
            listModel.addElement(server.getUsers());
        }
    }

    class FireListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            //This method can be called only if
            //there's a valid selection
            //so go ahead and remove whatever's selected.
            int index = list.getSelectedIndex();
            listModel.remove(index);

            int size = listModel.getSize();

            if (size == 0) { //Nobody's left, disable firing.
                fireButton.setEnabled(false);

            } else { //Select an index.
                if (index == listModel.getSize()) {
                    //removed item in last position
                    index--;
                }

                list.setSelectedIndex(index);
                list.ensureIndexIsVisible(index);
            }
        }
    }

    //This listener is shared by the text field and the hire button.
    class HireListener implements ActionListener, DocumentListener {
        private boolean alreadyEnabled = false;
        private JButton button;

        public HireListener(JButton button) {
            this.button = button;
        }

        //Required by ActionListener.
        public void actionPerformed(ActionEvent e) {
            String name = employeeName.getText();

            //User didn't type in a unique name...
            if (name.equals("") || alreadyInList(name)) {
                Toolkit.getDefaultToolkit().beep();
                employeeName.requestFocusInWindow();
                employeeName.selectAll();
                return;
            }

            int index = list.getSelectedIndex(); //get selected index
            if (index == -1) { //no selection, so insert at beginning
                index = 0;
            } else {           //add after the selected item
                index++;
            }

            listModel.insertElementAt(employeeName.getText(), index);
            //If we just wanted to add to the end, we'd do this:
            //listModel.addElement(employeeName.getText());

            //Reset the text field.
            employeeName.requestFocusInWindow();
            employeeName.setText("");

            //Select the new item and make it visible.
            list.setSelectedIndex(index);
            list.ensureIndexIsVisible(index);
        }

        //This method tests for string equality. You could certainly
        //get more sophisticated about the algorithm.  For example,
        //you might want to ignore white space and capitalization.
        protected boolean alreadyInList(String name) {
            return listModel.contains(name);
        }

        //Required by DocumentListener.
        public void insertUpdate(DocumentEvent e) {
            enableButton();
        }

        //Required by DocumentListener.
        public void removeUpdate(DocumentEvent e) {
            handleEmptyTextField(e);
        }

        //Required by DocumentListener.
        public void changedUpdate(DocumentEvent e) {
            if (!handleEmptyTextField(e)) {
                enableButton();
            }
        }

        private void enableButton() {
            if (!alreadyEnabled) {
                button.setEnabled(true);
            }
        }

        private boolean handleEmptyTextField(DocumentEvent e) {
            if (e.getDocument().getLength() <= 0) {
                button.setEnabled(false);
                alreadyEnabled = false;
                return true;
            }
            return false;
        }
    }

    //This method is required by ListSelectionListener.
    public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting() == false) {

            if (list.getSelectedIndex() == -1) {
            //No selection, disable fire button.
                fireButton.setEnabled(false);

            } else {
            //Selection, enable the fire button.
                fireButton.setEnabled(true);
            }
        }
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("ListDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent newContentPane = new Main();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
        Server.ServerStart(new String[] {"8080"});
    }
}
```

die code für die gui hab ich ausm internet, da bin ich so frei, da ich mich net so groß auseinandersetzen wollte, deshalb sind da auch noch so sachen wie fire und hire dabei.
und da mein programm nur prototypisch implementiert werden muss, ist das auch net ganz so dramatisch.
die gui an sich funktioniert, es geht nur um die sache mit dem update -.-


----------



## hdi (23. Jan 2009)

Hm ich muss sagen ich blicke nicht so richtig durch, habe aber in diesen client-server geschichten
wenig Erfahrung.

Versuch einfach mal folgendes:

in der GUI:


```
Server server = new Server(8080);
```

ersetzen durch:


```
Server server;
```

Und in der main-Methode:


```
this.server = Server.ServerStart(new String[] {"8080"});
```

Dafür musst du in der ServerStart Methode den Rückgabewert von void auf Server setzen und die Zeile


```
new Server(Integer.parseInt(x[0])).startServerListener();
```

ersetzen durch:


```
Server s = new Server(Integer.parseInt(x[0]));
s.startServerListener();
return s;
```


----------



## Man-in-Black (23. Jan 2009)

der tipp in der server-klasse ging so, aber in gui-klasse net

mh habs versucht aber dann kann ich das ganze nicht mal compilen, da er mir in der main methode beim start folgendes sagt:

```
...\rudi\Main.java:270: non-static variable this cannot be referenced from a static context
```

und die main methode muss static bleiben...


----------



## hdi (23. Jan 2009)

achso, ja klar sorry.

Lass createAndShowGui() das Main-Objekt returnen, und mach dann:


```
public static void main(String[] args) {
        Main m;
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                m  = createAndShowGUI();
            }
        });
        Server s = Server.ServerStart(new String[] {"8080"}); 
        m.setServer(s);
}
```

und in der GUI noch die Methode


```
public void setServer(Server s){
     this.server = s;
}
```

... das ist natürlich alles *extrem* scheisse gelöst, und eig. solltest du das alles wegwerfen und
neu anfangen, weil dein Code ist wirklich unter aller Sau mit den ganzen statischen Objekten usw.
Und meine Tipps hier sind dementsprechend auch alles andere als vorbildlich. Also... keine Ahnung
ob das funzt, aber selbst wenn, ist es schlecht.


----------



## Man-in-Black (23. Jan 2009)

jo es soll ja auch net schön sein... soll nur ne prototypische lösung werden... wenn ich lustig bin mach ich nach der bachelorarbeit dran weiter dann bau ich den schön


----------



## Man-in-Black (26. Jan 2009)

so ich habe nun mal die Vorschläge versucht umzusetzen, aber irgendwie geht das net so ganz, da er immer ne final-Variable voraussetzt.
final variablen kann ich aber nicht mehr ändern was hierbei aber ja passieren würde...langsam verzweifel ich daran echt...


----------



## Ebenius (26. Jan 2009)

hdi hat gesagt.:
			
		

> [...]
> 
> 
> 
> ...


hdi, dazu musst Du aber dem Compiler sehr viel Alkohol geben ... Wie soll das gehen?

Ebenius


----------



## hdi (26. Jan 2009)

Ohen das jetz in Eclipse gepastet zu haben, aber ich weiss grad echt nich wieso das nich gehen soll? Muss Main final sein, oder was meinst du?


----------



## Man-in-Black (26. Jan 2009)

ich programmier in netbeans.
und ja der motzt dass das Objekt m final sein muss, sonst kompiliert der das gar net


----------



## hdi (27. Jan 2009)

ja war n flüchtigkeitsfehler. Aber was Ebenius geschrieben hat klingt irgendwie nach "mehr", oder kam das nur so rüber?


----------



## Ebenius (27. Jan 2009)

Wie willst Du denn mit invokeLater eine Variable in die enclosing-class zuweisen? Wann soll denn das gesetzt werden? Weshalb ist denn gefordert, dass die Variablen final sind, damit sie an eine inner class abgegeben werden können? Kompilierbar ist's nicht und wird's nicht.


----------



## hdi (27. Jan 2009)

Hm also ich kanns akzeptieren, aber verstehen tu ich's nicht so ganz.
Wieso kann ich einer finalen Variable keinen Wert in einer inner class zuweisen? (Sonst geht es ja)


----------



## Ebenius (27. Jan 2009)

hdi hat gesagt.:
			
		

> Hm also ich kanns akzeptieren, aber verstehen tu ich's nicht so ganz.
> Wieso kann ich einer finalen Variable keinen Wert in einer inner class zuweisen? (Sonst geht es ja)


Das geht nie. Zeig mir ein Beispiel!


----------



## hdi (27. Jan 2009)

Mit "sonst" meine ich, wenn es sich nicht um eine inner class handelt:


```
final int x;
x=2;
```

Wieso funktioniert diese Zuweisung also nicht auch in einer inner class? Die Variable x hat ja
nix mit der inner class zu tun. (Mir ist auch grad wieder nich klar, wieso das nochmal final sein muss,
aber ich hatte das schon mal gefragt... muss mal den thread raussuchen)


----------



## Ebenius (27. Jan 2009)

Nur ein Beispiel: 
	
	
	
	





```
final int x;
new Thread(new Runnable() {
  public void run() {
    try {
      Thread.sleep(60*60*1000);
    } catch (InterruptedException ex) {
    }
    x = 4;
  }
}).start();
System.out.println(x);
```
Soll jetzt Zeile 10 eine Stunde warten, bis x gesetzt wurde?

Ebenius


----------



## hdi (27. Jan 2009)

edit: Okay hab jetzt geschnallt was du damit sagen willst.

Aber mir ist noch nicht klar: Reden wir hier von inner classes im Allgemeinen, oder nur von inner classes
die Runnable sind?


----------



## Ebenius (27. Jan 2009)

Selbes Beispiel: 
	
	
	
	





```
final int x;
button.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    x = 4;
  }
});
System.out.println(x);
```
Soll jetzt Zeile 7 jetzt warten, bis ein Trottel einen Button klickt?

Ebenius


----------



## hdi (27. Jan 2009)

Okay.. aber was hat's mit inner classes zu tun?
Wenn ich dem Button einem Listener zuweise, und nicht per inner class,
hat man doch irgendwie das gleiche Problem?

Sagen wir der Listener weist der globalen final Variable etwas zu..


edit: Achso dann lässt es sich nicht kompilieren weil bei dem Sys-out eine Meldung "may not have been initialized" kommt oder?

edit2: So, jetzt ist's eingeschlagen  Mir ist es grad etwas aus dem Fokus verronnen, dass inner classes
ja nur eine Methode definieren, die aufgerufen werden _kann_. Aber sie ist nicht Teil der sequentiellen Abarbeitung, deshalb kann man nicht sagen was genau passiert oder ob etwas passiert. Alles klar


----------



## Ebenius (27. Jan 2009)

hdi... in Java gibt's keine globalen Variablen. Wenn Du Member-Variablen meinst die final sind: Die müssen im Konstruktor gesetzt werden, sonst Compiler-Error...


----------



## hdi (27. Jan 2009)

Jo dachte an statics, das versteh ich unter "global", also nicht member-variablen. Aber hab grad gesehen dass man denen direkt nen Wert zuweisen muss. Alles klar jetz, danke


----------



## Ebenius (27. Jan 2009)

hdi hat gesagt.:
			
		

> edit2: So, jetzt ist's eingeschlagen  Mir ist es grad etwas aus dem Fokus verronnen, dass inner classes
> ja nur eine Methode definieren, die aufgerufen werden _kann_. Aber sie ist nicht Teil der sequentiellen Abarbeitung, deshalb kann man nicht sagen was genau passiert oder ob etwas passiert. Alles klar


 :toll: Jetzt wird's richtig! Jetzt musst Du nur noch den Begriff "globale Variable" aus Deinem Kopf bekommen, dann wird alles gut. ;-)


----------



## Ebenius (27. Jan 2009)

hdi hat gesagt.:
			
		

> Jo dachte an statics, das versteh ich unter "global", also nicht member-variablen. Aber hab grad gesehen dass man denen direkt nen Wert zuweisen muss. Alles klar jetz, danke


statics final's müssen entweder bei der Deklaration oder in einem static initializer zugewiesen werden.


----------



## hdi (27. Jan 2009)

Jo, dafür mach ich mir ein Gehirn-Branding gleich neben "in Java gibt's kein Call-By-Reference"


----------



## Ebenius (27. Jan 2009)

hdi hat gesagt.:
			
		

> Jo, dafür mach ich mir ein Gehirn-Branding gleich neben "in Java gibt's kein Call-By-Reference"


Den Satz am besten auch noch loswerden. Der stimmt zwar, wenn man ihn verstanden hat. Wenn man ihn aber in ein Forum postet, führt's meist zu Verwirrung, weil ja Referenzen by value übergeben werden... Dort gibt der Durchschnitts-Fragesteller ad hoc auf. :-D


----------



## hdi (27. Jan 2009)

> Den Satz am besten auch noch loswerden. Der stimmt zwar, wenn man ihn verstanden hat.



Ja ich verstehe es.



> Wenn man ihn aber in ein Forum postet, führt's meist zu Verwirrung, weil ja Referenzen by value übergeben werden... Dort gibt der Durchschnitts-Fragestiller ad hoc auf.



Mag ja sein aber trotzdem merk ich _mir_ das so, wie es ist


----------



## Leroy42 (27. Jan 2009)

hdi hat gesagt.:
			
		

> Sagen wir der Listener weist der globalen final Variable etwas zu..



Einer *final*-Variablen etwas in einem _Listener_ zuzuweisen ist schon ziemlich hirni. 
 



			
				hdi hat gesagt.:
			
		

> Mag ja sein aber trotzdem merk ich _mir_ das so, wie es ist



 :applaus:  :applaus:  :applaus: 

Richtig! Gerade in einem Forum etwas _Halbfalsches_ als _Lernhilfe_ stehen zu lassen, lehne ich ab.


----------



## hdi (27. Jan 2009)

@Leroy

Soll man jetzt hier im Forum nichts mehr schreiben dürfen, das evtl ein Anfänger missverstehen könnte, weil er keinen Plan hat? Wenn ein User hier nen Thread aufmacht und fragt, ob es Call-By-Reference gibt, würde ich nicht nur "Ne" sagen sondern ihm das schon genauer erklären.
Aber darum geht's in diesem Thread überhaupt nicht.

Ausserdem ist daran nichts halbfalsch, noch nicht mal ein achtel falsch. Es ist einfach nur 100% korrekt,
dass es in Java kein Call-By-Reference gibt. Denn das ist ein spezieller Ausdruck aus der Informatik, der ein bestimmtes Verhalten beschreibt, das es in Java einfach gar nicht gibt.

Und als "Lernhilfe" hab ich das erst recht nicht gelabelt, das war ein eingestreuter Satz in einer OT-Diskussion.

Aber um deine innere Ruhe wiederherzustellen, und für alle Anfänger die sich vllt irgendwie hierher verirren
und nun evtl. "Halbfalsches" Wissen haben:

"Call by Reference" in Java


----------



## Leroy42 (28. Jan 2009)

:shock: 

Du hast mich vollkommen mißverstanden! 

Ich meinte, ich _finde auch_, daß es keinen Sinn macht, Anfänger
mit _halb-falschen_ Wissen zu verwirren.

Natürlich gibt es in Java kein _call-by-reference_ und das soll
auch deutlich klargestellt werden.

Aber okay, meine Wortschöpfung _halbfalsch_ ist ungünstig gewählt   



			
				hdi hat gesagt.:
			
		

> Soll man jetzt hier im Forum nichts mehr schreiben dürfen, das evtl ein Anfänger missverstehen könnte, weil er keinen Plan hat?



Eben nicht! Genau das Gegenteil versuchte ich, durch mein Posting zu bewirken.



			
				hdi hat gesagt.:
			
		

> Wenn ein User hier nen Thread aufmacht und fragt, ob es Call-By-Reference gibt, würde ich nicht nur "Ne" sagen sondern ihm das schon genauer erklären.



Richtig!



			
				hdi hat gesagt.:
			
		

> Und als "Lernhilfe" hab ich das erst recht nicht gelabelt, das war ein eingestreuter Satz in einer OT-Diskussion.



Ich meinte mit "Lernhilfe" Postings derer, die _aber das ist doch call-by-reference_ als Aussage stehen
lassen könnten.



			
				hdi hat gesagt.:
			
		

> Aber um deine innere Ruhe wiederherzustellen, und für alle Anfänger die sich vllt irgendwie hierher verirren und nun evtl. "Halbfalsches" Wissen haben:
> 
> "Call by Reference" in Java



 :applaus:  :applaus:  :applaus: 

(Meine innere Ruhe ist jetzt wiederhergestellt, wo ich klargestellt habe, daß ich dich
keineswegs angreifen wollte, sondern genau so denke wie du   )


----------



## Leroy42 (28. Jan 2009)

Also eigentlich müßte Ebenius sich angegriffen fühlen.


----------



## Ebenius (28. Jan 2009)

Leroy42 hat gesagt.:
			
		

> Also eigentlich müßte Ebenius sich angegriffen fühlen.


Hatte ich auch anders herum verstanden. Liegt wohl daran, dass der Applaus-Hans ( :applaus: ) eher ironisch wirkt. Angegriffen fühle ich mich mal net. 

Ich hatte ursprünglich lediglich darauf hinweisen wollen, dass man solche Schlagwörter wie _call by reference_ am besten nicht einfach so einstreut. Wenn man das einfach in irgendeinen Anfänger-Thread reinschmeißt, ohne zu erklären was es bedeutet, dann ist dem Leser wenig geholfen. Es verwirrt meist nur. Der Grund warum ich das anmerke: Ich habe in den letzten Wochen einige Threads gesehen, wo genau das passiert ist.

Just my $0.02

Ebenius


----------



## Leroy42 (28. Jan 2009)

Ebenius hat gesagt.:
			
		

> Leroy42 hat gesagt.:
> 
> 
> 
> ...



 :shock: Also applaudieren tue ich nie ironisch!   

Aber daß das so hätte verstanden werden können, ist natürlich mein Fehler! (  )



			
				Ebenius hat gesagt.:
			
		

> Ich hatte ursprünglich lediglich darauf hinweisen wollen, dass man solche Schlagwörter wie _call by reference_ am besten nicht einfach so einstreut.



Sehe ich nicht so, da _call-by-reference_ eine eindeutige Definition besitzt.

... und ob Anfänger oder nicht ist mir da vollkommen egal.

Aber okay: Beenden wir den Krieg!  :toll:


----------

