try-catch, call-by-reference, Streaming und Strings

Status
Nicht offen für weitere Antworten.

maxxi

Bekanntes Mitglied
Hello :meld:

ich habe mein erstes total kompliziertes Java-Programm fertig :applaus:

Aber da sind echt so viele neue, schwere Sachen, es hätte mich interessiert, ob ich das wirklich alles richtig gemacht haben. Im Programm habe ich:

- Threads
- Streaming
- ErrorHandling
- Sockets

Das ist das Programm:
Java:
import java.net.*; // Socket
import java.io.*;  // Input-/Output-Stream
public class Server
{  public static void man (String[] arrArg)
   {  try
      {  ServerSocket oSS=new ServerSocket(80); // Port; ev. IOException
         while(true)
         {  Socket oS=oSS.accept();             // blockiert; wartet auf Client; ev. IOException
            (new ServerThread(oS)).start();     // ruft ServerThread.run() auf; ev. IllegalThreadStateException
         }
      }
      catch(Exception oE)
      {  System.err.println(oE.toString());
      }
   }
}
class ServerThread extends Thread
{  private Socket _oS;
   public ServerThread(Socket oS)
   {  this._oS=oS;
   }
   public void run()
   {  StringBuffer oSB=new StringBuffer();
      try
      {  InputStream  oIS=this._oS.getInputStream();  // ev. IOException
         OutputStream oOS=this._oS.getOutputStream(); // ev. IOException
         int iC;
         while((iC=oIS.read())!=-1)                   // ev. IOException
            oSB.append((char)iC);
         oOS.write((oSB.toString()).getBytes());      // ev. IOException
      }
      catch(IOException oE)
      {  System.err.println(oE.toString());
      }
      try
      {  this._oS.close();                            // ev. IOException
      }
      catch(IOException oE)
      {  System.err.println(oE.toString());
      }
   }
}

Mich würden interessieren:

- Habe ich das richtig gemacht, dass ich close in ein eigenes try-catch gegeben habe? In meinem Buch ist das nämlich nicht so. Ich dachte, dass close auf jeden Fall ausgeführt werden muss, falls es davor im ServerThread irgendwelche Probleme gab. Könnte man das vielleicht noch irgendwie vereinfachen?

- ServerThread erhält das this._oS von Server. Server übergibt das oS als call-by-reference, ist das richtig? Wenn ich also im ServerThread ein this._oS.close(); ausführe, wird das oS im Server geschlossen, stimmt das?

- Im Server verwende ich ein catch(Exception oE). In meinem Buch steht catch(IOException oE). Das habe ich geändert, weil start() eine IllegalThreadStateException auslösen könnte. Ist das richtig, dass mein catch IOException und IllegalThreadStateException abfängt? Habe ich diesen catch richtig programmiert?

- Ist das OK, dass ich vor ServerThread kein public gesetzt habe? Was ist das dann eigentlich? protected? Nur innerhalb des eigenen Pakets sichtbar? Ich habe das so gemacht, weil ich die beiden Klassen in 1 Datei haben wollte. Ist das OK?

- Ist das Programm - ganz allgemein betrachtet - OK? Stil OK? Vielleicht noch irgendwelche Fehler oder sonst etwas, was ich noch machen sollte?

- Gibt es eigentlich eine Möglichkeit, wie ServerThread Fehler an Server melden kann? Wenn also in run eine Exception auftritt, dass diese an Server weitergeleitet wird und erst in Server die eigentliche Fehlerbehandlung durchgeführt wird?

Eure Meinung würde mich echt interessieren. Das ist mein erstes komplizierte Java-Programm :)
 
Zuletzt bearbeitet:

tfa

Top Contributor
- Habe ich das richtig gemacht, dass ich close in ein eigenes try-catch gegeben habe? In meinem Buch ist das nämlich nicht so. Ich dachte, dass close auf jeden Fall ausgeführt werden muss, falls es davor im ServerThread irgendwelche Probleme gab. Könnte man das vielleicht noch irgendwie vereinfachen?
Grundsätzlich ist das richtig. Du solltest das close() aber in einem finally-Block schreiben, damit es auf jeden Fall ausgeführt wird. Warum schließt du den in-Stream nicht?

- ServerThread erhält das this._oS von Server. Server übergibt das oS als call-by-reference, ist das richtig? Wenn ich also im ServerThread ein this._oS.close(); ausführe, wird das oS im Server geschlossen, stimmt das?
Es gibt kein Call-by-Reference in Java. Du übergibst eine Referenz auf den (einzigen) Stream an die Methode.

- Im Server verwende ich ein catch(Exception oE). In meinem Buch steht catch(IOException oE). Das habe ich geändert, weil start() eine IllegalThreadStateException auslösen könnte. Ist das richtig, dass mein catch IOException und IllegalThreadStateException abfängt? Habe ich diesen catch richtig programmiert?
An solchen Stellen solltest du niemals alle Exceptions fangen. Immer nur die Exceptions, die auch geworfen werden können. Das ist zwar umständlich, wird mit Java 7 aber etwas vereinfacht.

- Ist das OK, dass ich vor ServerThread kein public gesetzt habe? Was ist das dann eigentlich? protected? Nur innerhalb des eigenen Pakets sichtbar? Ich habe das so gemacht, weil ich die beiden Klassen in 1 Datei haben wollte. Ist das OK?
Die Klasse ist nur innerhalb des Paketes sichtbar. Trotzdem sollte man jede Top-Level-Klasse in eine Datei speichern. Das dient der Übersicht. Für kleine Spielereien ist es aber OK so.

- Ist das Programm - ganz allgemein betrachtet - OK? Stil OK? Vielleicht noch irgendwelche Fehler oder sonst etwas, was ich noch machen sollte?
Dein Klammerungs-Stil ist ungewöhnlich. Die Variblen könntest du sprechender benennen. Unterstriche haben in Variablennamen nichts zu suchen.
 
Zuletzt bearbeitet:

Landei

Top Contributor
Normalerweise (genauer gesagt, solange du nicht von mehreren Threads darauf zugreifst, was die absolute Ausnahme sein sollte) solltest du StringBuilder statt StringBuffer verwenden, was deutlich schneller ist.
 

tfa

Top Contributor
Normalerweise (genauer gesagt, solange du nicht von mehreren Threads darauf zugreifst, was die absolute Ausnahme sein sollte) solltest du StringBuilder statt StringBuffer verwenden, was deutlich schneller ist.
Deutlich schneller? Kann ich mir nicht vorstellen. Hast du da einen Benchmark?
 
B

bygones

Gast
Deutlich schneller? Kann ich mir nicht vorstellen. Hast du da einen Benchmark?
synchronized gegen nicht synchronized... ergo schneller

ueber das Ausmass laesst sich natuerlich streiten... wir sprechen hier nicht von grossen O unterschieden


aber zb StringBuffer vs. StringBuilder performance comparison | Little Tutorials
So StringBuilder is faster by a good percentage (34% on my machine in this case) but remember that it is not thread safe

und doc:
This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.
 
Zuletzt bearbeitet von einem Moderator:

tfa

Top Contributor
wir sprechen hier nicht von grossen O unterschieden
Das will ich meinen. Synchronisation ist nicht mehr so teuer wie in der Vergangenheit. Außerdem könnte ein JIT die wegoptimieren, wenn bewiesen ist, dass das Objekt nur lokal verwendet wird.
Aber grundsätzlich sollte man natürlich den Builder bevorzugen.
 

maxxi

Bekanntes Mitglied
Wow, das waren schon mal mächtig viele Infos :)
Grundsätzlich ist das richtig. Du solltest das close() aber in einem finally-Block schreiben, damit es auf jeden Fall ausgeführt wird.
Mal 2 Beispiele:
Beispiel 1:
Java:
try
{  throw new Exception();
}
catch(Exception oE)
{  System.out.print("error");
}
System.out.print("ende");
Beispiel 2:
Java:
try
{  throw new Exception();
}
catch(Exception oE)
{  System.out.print("error");
}
finally
{  System.out.print("ende");
}
Wo liegt denn der Unterschied? "ende" wird doch in beiden Beispielen (egal ob mit oder ohne Exception) immer ausgegeben, oder?
Warum schließt du den in-Stream nicht?
Das geht? Wird in keinem einzigen Beispiel in meinem Buch gemacht. Hm ... muss ich noch nachforschen.
Dann muss ich doch den out-Stream auch schließen, oder?
An solchen Stellen solltest du niemals alle Exceptions fangen. Immer nur die Exceptions, die auch geworfen werden können.
Worin liegt denn der Vorteil, wenn ich die Exceptions alle extra abfange? Ist doch - speziell bei großen Programmen - ein ziemlicher Programmieraufwand, oder?
Das ist zwar umständlich, wird mit Java 7 aber etwas vereinfacht.
In Java 7 verändert sich das Verhalten beim try-catch-finally?
Dein Klammerungs-Stil ist ungewöhnlich.
Mit gefällt der, weil { und } immer untereinander stehen. Sollte das { irgendwo gaaaanz rechts stehen, wo ich scrollen muss, um es zu sehen, finde ich das nicht so schön übersichtlich :)
Unterstriche haben in Variablennamen nichts zu suchen.
Das mache ich, um schon anhand des Namens private/protected-Methoden/Eigenschaften von public Methoden/Eigenschaften unterscheiden zu können. Könnte es damit Probleme geben?
that it is not thread safe
Darauf habe ich noch überhaupt nicht geachtet. Stimmt das, dass ich in ServerThread nur Sachen verwenden darf, die thread-sicher sind? Wie erkenne ich denn, welche Methode oder Eigenschaften von welchen Klassen das sind??
 
B

bygones

Gast
Wo liegt denn der Unterschied? "ende" wird doch in beiden Beispielen (egal ob mit oder ohne Exception) immer ausgegeben, oder?
bei einem finally ist gewaehrleistet dass der code auf alle faelle ausgefuehrt wird bevor die methode verlassen wird (egal ob ueber return oder ein fehler)... in deinem bsp macht dies keinen unterschied

Das geht? Wird in keinem einzigen Beispiel in meinem Buch gemacht. Hm ... muss ich noch nachforschen.
Dann muss ich doch den out-Stream auch schließen, oder?
jeden stream sollte man schliessen

Das mache ich, um schon anhand des Namens private/protected-Methoden/Eigenschaften von public Methoden/Eigenschaften unterscheiden zu können. Könnte es damit Probleme geben?
ich sehe es nicht so besorgniserregend an wenn eine Variable mit _ beginnt... wenn man mit einer IDE arbeitet kann man sich alle moeglichen kombinationen farblich markieren, um unterscheiden zu koennen.
Probleme gibt es auf alle faelle nicht, es ist eine Geschmackssache.
 

tfa

Top Contributor
Worin liegt denn der Vorteil, wenn ich die Exceptions alle extra abfange? Ist doch - speziell bei großen Programmen - ein ziemlicher Programmieraufwand, oder?
Exceptions fängt man eigentlich nur dann ab, wenn man sie auch behandelt. In deinem Beispiel gibt's du sie ja einfach nur aus. Also macht es hier keinen Unterschied.
In Java 7 verändert sich das Verhalten beim try-catch-finally?
In Java 7 kann man in einer catch-Klausel mehrere unterschiedliche Exceptions fangen.

Das mache ich, um schon anhand des Namens private/protected-Methoden/Eigenschaften von public Methoden/Eigenschaften unterscheiden zu können. Könnte es damit Probleme geben?
Wie gesagt, es ist eine Stil-Frage. Ich finde, es ist schwer zu schreiben und schwer zu lesen und hat dabei keinen richtigen Vorteil.

Darauf habe ich noch überhaupt nicht geachtet. Stimmt das, dass ich in ServerThread nur Sachen verwenden darf, die thread-sicher sind? Wie erkenne ich denn, welche Methode oder Eigenschaften von welchen Klassen das sind??
In deinem Beispiel verwendest du den StringBuffer nur lokal in einer Methode. Andere Threads können den gar nicht sehen. Also braucht man hier keine Threadsicherheit und kannst StringBuilder verwenden.
 

maxxi

Bekanntes Mitglied
Jetzt habe ich noch 3 close eingebaut:
Java:
import java.net.*; // Socket
import java.io.*;  // Input-/Output-Stream
public class Server
{  public static void man (String[] arrArg)
   {  try
      {  ServerSocket oSS=new ServerSocket(80); // Port; ev. IOException
         try
         {  while(true)
            {  Socket oS=oSS.accept();          // blockiert; wartet auf Client; ev. IOException
               (new ServerThread(oS)).start();  // ruft ServerThread.run() auf; ev. IllegalThreadStateException
            }
         }
         catch(Exception oE)
         {  System.err.println(oE.toString());
         }
         oSS.close();
      }
      catch(Exception oE)
      {  System.err.println(oE.toString());
      }
   }
}
class ServerThread extends Thread
{  private Socket _oS;
   public ServerThread(Socket oS)
   {  this._oS=oS;
   }
   public void run()
   {  StringBuffer oSB=new StringBuffer();
      try
      {  InputStream oIS=this._oS.getInputStream();      // ev. IOException
         try
         {  OutputStream oOS=this._oS.getOutputStream(); // ev. IOException
            try
            {  int iC;
               while((iC=oIS.read())!=-1)                // ev. IOException
                  oSB.append((char)iC);
               oOS.write((oSB.toString()).getBytes());   // ev. IOException
            }
            catch(IOException oE)
            {  System.err.println(oE.toString());
            }
            oOS.close();
         }
         catch(IOException oE)
         {  System.err.println(oE.toString());
         }
         oIS.close();
      }
      catch(IOException oE)
      {  System.err.println(oE.toString());
      }
      try
      {  this._oS.close();                               // ev. IOException
      }
      catch(IOException oE)
      {  System.err.println(oE.toString());
      }
   }
}
Jetzt habe ich mächtig viele try-catch. Geht das noch irgendwie einfacher?

Aber 2 Fragen sind jetzt noch übriggeblieben:
- Wie erkenne ich, was in Java threadsicher ist?
- Kann ich im run Exception irgendwie an Server weiterreichen?
 
Zuletzt bearbeitet:

Painii

Bekanntes Mitglied
Das mache ich, um schon anhand des Namens private/protected-Methoden/Eigenschaften von public Methoden/Eigenschaften unterscheiden zu können. Könnte es damit Probleme geben?
Probleme nicht, ist halt nur komisch zu lesen...

Darauf habe ich noch überhaupt nicht geachtet. Stimmt das, dass ich in ServerThread nur Sachen verwenden darf, die thread-sicher sind? Wie erkenne ich denn, welche Methode oder Eigenschaften von welchen Klassen das sind??
Du darfst in threads auch dinge verwenden die nicht thread-safe sind, aber da kannst du inkonsistente Daten erhalten und viele andere schöne Dinge...

Beispiel:
Ein Thread soll von einem Objekt eine Variable erhöhen->
Java:
public class ObjektIncrement{
 private int zahl=0;
 public void inc(){
  zahl = zahl+1;
 }
}
Java:
public class AddThread implements Runnable{
 private ObjektIncrement o;
 public AddThread(ObjektIncrement o){
  this.o=o;
 }
 public void run(){
  for(int i=0;i<500;i++){
   o.inc();
  }
 }
 public static void main(String[] args){
  ObjektIncrement o = new ObjektIncrement;
  new Thread(AddThread(o).start());
  new Thread(AddThread(o).start());
 }
}

inc() kann man ja aufschlüsseln zu:
Java:
 int r=zahl;
 r++;
 zahl=r;
Nach jeder Anweisung kann nun ein anderer Thread an die Reihe kommen!
Was passiert nun wenn zwei Threads bei o inc() aufrufen?
3 Fälle, erst wird ein Thread abgearbeitet, dann der andere, die 2 Fälle sind ok so.
Der letzte Fall hat aber ein Problem:
Nebenläufig:
Java:
Thread1:
r1 = zahl //zahl ist 0, also r1=0
r++;
Thread2:
r2 = zahl //zahl ist immer noch 0, also r2=0  
Thread1:
zahl=r1 //r1=1, also zahl=1
//Thread 1 fertig.
Thread2:
r2++ //r2=1
zahl=r2; //r2=1, zahl=1

Zum Schluss wurde zweimal inc() aufgerufen, aber zahl hat sich nur um 1 erhöht.

Aber bei deinem Thread ist das soweit noch kein Problem...
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
T catch(InputMismatchException) wird nicht ausgefürt/erkannt Java Basics - Anfänger-Themen 12
missy72 Catch Blöcke zusammenfassen Java Basics - Anfänger-Themen 6
Ostkreuz wie geht der catch? Java Basics - Anfänger-Themen 3
D try/catch-Block bei for-Schleife Java Basics - Anfänger-Themen 14
D Best Practice Ausgabe über direkte Ausgabe oder try-catch? Java Basics - Anfänger-Themen 13
districon Try - Catch Java Basics - Anfänger-Themen 8
JavaNoobi Try and Catch und übergabe von Objekten Java Basics - Anfänger-Themen 2
Y Wie kann ich die Variable in der Try Catch returnen? Java Basics - Anfänger-Themen 3
B Try-Catch Block Java Basics - Anfänger-Themen 3
B JUnit / Exceptions/ try-catch Java Basics - Anfänger-Themen 6
B try catch finally Java Basics - Anfänger-Themen 2
F Mehrere Exceptions in einem Catch-Block abfangen Java Basics - Anfänger-Themen 12
H throws und try catch Java Basics - Anfänger-Themen 8
H Try Catch Throw Exception Java Basics - Anfänger-Themen 1
S Try-Catch in Verwendung einer while Schleife Java Basics - Anfänger-Themen 2
I Try-Catch innerhalb eines Catchblocks Java Basics - Anfänger-Themen 1
J Endlosschleife bei Try-Catch? Java Basics - Anfänger-Themen 3
K JOptionPane/catch/try/finally/if Java Basics - Anfänger-Themen 9
V InputMismatchException (Try and catch) Java Basics - Anfänger-Themen 10
L do-while-Schleife läuft doppelt, try catch fehler Java Basics - Anfänger-Themen 12
J Erste Schritte catch Exeption Parameter Java Basics - Anfänger-Themen 7
TheMenox Try and Catch Java Basics - Anfänger-Themen 12
J Try Catch Java Basics - Anfänger-Themen 6
DeVolt Java8 Paket Time: Datum prüfen / try-catch Java Basics - Anfänger-Themen 1
J Code in Try-Catch Block wird nicht komplett ausgeführt Java Basics - Anfänger-Themen 5
J Frage zum Thema Exceptions (Try/Catch) Java Basics - Anfänger-Themen 3
A Nicht zu findender Fehler in einem try/catch Block Java Basics - Anfänger-Themen 6
F try/catch Ausführungen ? Java Basics - Anfänger-Themen 3
S try-catch - Variablen werden nicht an return übergeben Java Basics - Anfänger-Themen 3
Z Catch & Exceptions Java Basics - Anfänger-Themen 4
I Exception try-catch Java Basics - Anfänger-Themen 1
E Buchstaben verhindern / Try & Catch Block Java Basics - Anfänger-Themen 3
F try/catch - (else) Java Basics - Anfänger-Themen 11
L Warum ist der catch-Block nicht erreichbar ? Java Basics - Anfänger-Themen 8
C Problem mit try-catch in Schleife Java Basics - Anfänger-Themen 15
R Exceptions (try/catch) Java Basics - Anfänger-Themen 63
H Geht dieser Code noch einfacher (try catch finally) Java Basics - Anfänger-Themen 7
J Methoden try / catch exception Java Basics - Anfänger-Themen 5
S 'continue' in catch- und if-blöcken Java Basics - Anfänger-Themen 2
B Erste Schritte try-catch-Klauseln, überprüfte Ausnahmen Java Basics - Anfänger-Themen 4
D Erste Schritte Warum try-catch für FileWriter Java Basics - Anfänger-Themen 5
S try-catch-finally-Problem Java Basics - Anfänger-Themen 10
xehpuk Compiler-Fehler final Variable in try-catch Wert zuweisen Java Basics - Anfänger-Themen 8
F Exceptionbehandlung --> catch/throws Java Basics - Anfänger-Themen 11
M Try und Catch Java Basics - Anfänger-Themen 5
B Fehler mit try + catch verhindern Java Basics - Anfänger-Themen 8
N Catch Block in Try erzwingen Java Basics - Anfänger-Themen 14
E Problem mit for schleife/ try-catch block Java Basics - Anfänger-Themen 7
B Variablen Variablen in try / catch "public" machen? Java Basics - Anfänger-Themen 3
C Wiederholung von try-catch Java Basics - Anfänger-Themen 3
N try and catch block in finally Java Basics - Anfänger-Themen 8
M exception catch falsch? Java Basics - Anfänger-Themen 11
S catch Exception erklären Java Basics - Anfänger-Themen 2
C Variable in try/catch Java Basics - Anfänger-Themen 10
B Try and Catch Java Basics - Anfänger-Themen 6
StrikeTom Ein paar(2) Fragen zu throws und try + catch Java Basics - Anfänger-Themen 6
J try und catch Java Basics - Anfänger-Themen 7
G Exceptionfreie Anweisungen in try-catch-Blöcke, Java Basics - Anfänger-Themen 6
B Exception vor catch Block definieren Java Basics - Anfänger-Themen 9
M Frage zu try ... catch Java Basics - Anfänger-Themen 9
S NumberFormatException , mit Try/Catch? Java Basics - Anfänger-Themen 7
B Try/catch Java Basics - Anfänger-Themen 11
M Try & Catch Java Basics - Anfänger-Themen 7
V Was ist ein Try-Catch Block Java Basics - Anfänger-Themen 4
M Nach catch mit der schleife weitermachen Java Basics - Anfänger-Themen 9
S sauberer Stil von return Wert (try, catch, finally) Java Basics - Anfänger-Themen 9
S try-catch Java Basics - Anfänger-Themen 10
Tandibur Server führt "try-catch" nicht aus Java Basics - Anfänger-Themen 6
H Falsche Eingabe über try-catch abfangen Java Basics - Anfänger-Themen 2
I Frage zu Try - Catch - Finally Java Basics - Anfänger-Themen 10
Daniel_L Verwendung von try und catch bei exceptions Java Basics - Anfänger-Themen 7
GambaJo Wann try.catch nutzen? Java Basics - Anfänger-Themen 11
H try catch Java Basics - Anfänger-Themen 4
I double-Variable außerhalb des Try-Catch-Blocks nicht gültig Java Basics - Anfänger-Themen 2
D Catch wiederholt sich ständig Java Basics - Anfänger-Themen 2
T try-catch-finally Java Basics - Anfänger-Themen 8
G Anwendung von try-catch Java Basics - Anfänger-Themen 10
G try. catch Verwendung Java Basics - Anfänger-Themen 11
M Try-Catch-Problem Java Basics - Anfänger-Themen 4
G habe ein Catch problem Java Basics - Anfänger-Themen 7
C Nach Catch-Klausel Programm weiter laufen lassen Java Basics - Anfänger-Themen 5
B try & catch Problem mit Exception bzw String.split() Java Basics - Anfänger-Themen 5
C Frage zu try - catch (saubere Lösung?) Java Basics - Anfänger-Themen 3
G Bei catch beenden Java Basics - Anfänger-Themen 7
U catch mit finally Java Basics - Anfänger-Themen 5
C Exceptions, try, catch --> Frage Java Basics - Anfänger-Themen 7
J Try-Catch-Frage Java Basics - Anfänger-Themen 13
B catch exception funktioniert nicht! Java Basics - Anfänger-Themen 14
D Frage try and catch Java Basics - Anfänger-Themen 7
ven000m try catch - was muss bei catch rein Java Basics - Anfänger-Themen 28
G Datenbank - catch Java Basics - Anfänger-Themen 2
H Konstruktor in Methode fremder Klasse: try-catch-Problem Java Basics - Anfänger-Themen 4
M return und try-catch Java Basics - Anfänger-Themen 6
M Try . catch erzwungen? Java Basics - Anfänger-Themen 11
F eigene Exception aus try-catch werfen Java Basics - Anfänger-Themen 10
A Syntaxproblem mit try und catch Java Basics - Anfänger-Themen 3
Silver-Blue fragen zu Swing und catch Exceptions Java Basics - Anfänger-Themen 2
G return fehler bei try catch Java Basics - Anfänger-Themen 8
H try und catch Java Basics - Anfänger-Themen 6
A try catch UNREACHABLE CODE Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben