Java Programmierung

Kap.3:   APPLIKATIONEN


Kapitel-Index
     3.1 Hauptprogramm mit main
     3.2 Lokale Variablen-Vereinbarungen
     3.3 System-Programmierung
     3.4 Graphik als Applikation
     3.5 Testfragen
  Eine Applikation ist ein direkt innerhalb des Betriebssystems ablaufendes (appliziertes) Programm (stand alone program) mit Ein/ Ausgabe über Konsole oder über Fenster-Graphik. Applikationen werden stets mit der Haupt-Methode main(String[]) gestartet (3.1), ermöglichen System-Programmierung (3.3) und - umständlicher als bei Applets (13.3) - auch Graphik-Programmierung (3.4).

3.1      Hauptprogramm mit main

  Die (Haupt-)Methode, die zu Anfang als Hauptprogramm aufgerufen wird, trägt den Namen main. Sie muss innerhalb einer Klasse vereinbart werden und dann unter dem Namen dieser (Haupt-)Klasse aufgerufen werden. Dazu muss der Name der (Haupt-)Klasse mit dem Namen der Datei übereinstimmen, in dem diese Klasse editiert und gespeichert wurde, abgesehen von der Datei-Erweiterung .java. Die Methode main wird vereinbart als
           public static void main(String[] args) { ... }
  public ist ein Zugriff-Modifizierer (Syntax.070) für Zugriff im selben und in verwandten Paketen, static ist ein Methoden-Modifizierer (Syntax.070) für den Aufruf ohne speicheraufwendige Objektbildung und void ist der leere Ergebnistyp (Syntax.031), d.h. main liefert keinen Ergebniswert. Der Methoden-Rumpf ist ein Block.
068: Block                        Block           
    HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
    H       ,--------------------------------------,          H
    H       | B  l  o  c k  S  t  a  t  e  m e n t |          H
    H       |    ,--------------------------,      |          H
    H -> { -+--->| LocalVariableDeclaration |-> ; -| ,-> } -> H
    H       | |  '--------------------------'      | |        H                                
    H       | |  ,------------------,              | |        H
    H       | |->| ClassDeclaration |--------------| |        H
    H       | |  '------------------'of local class| |        H
    H       | |  ,-----------,                     | |        H
    H       | '->| Statement |---------------------' |        H
    H       |    '-----------'                       |        H                                
    H       '----------------------------------------'        H
    HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

     z.B.   {out.print("§"); String s=args[0]; out.print(s);}
  Ein Block (Syntax.068, siehe oben) besteht aus geschweiften Klammern { } und darin enthaltenen Blockanweisungen (BlockStatement), u.a. lokale Variablen-Vereinbarungen und Anweisungen. Wie das Syntaxdiagramm und das Kurzbeispiel zeigen, muss eine lokale Variablen-Vereinbarung nicht notwendig am Anfang des Blocks stehen, nur vor dem Aufruf ihrer Variablen (eine kontextsensitive Zusatzregel zum kontextfreien Syntaxdiagramm).

  Im folgenden Programm UmsatzSteuer ist der formale Parameter String[] args von main eine Reihung aus zwei Komponenten args[0] und args[1], die beim Aufruf von main mit dem Java-Kommando
                    java UmsatzSteuer USt umsatz
mit den aktuellen Argumenten Umsatzsteuer-Prozentsatz USt und Umsatz-Betrag umsatz besetzt werden. Bei Aufruf von main mit falscher Argumentlänge wird das Programm mit return abgebrochen
    if(args.length!=2)
     {out.println("java UmsatzSteuer USt umsatz");return;}
und der Benutzer auf das richtige Java-Kommando hingewiesen. Die resultierende Umsatzsteuer wird formatiert mit printf(String, Object...) ausgegeben.
//********************** UmsatzSteuer.java ***********************
//                  Berechnung der Umsatzsteuer                  *
//      args[0],args[1] Eingabe, formatierte printf-Ausgabe      *
//            Command: java UmsatzSteuer USt umsatz              *
//****************************************************************
//            java.lang.                                 Object
import static java.lang.System.out;                    // |`System
import static java.lang.Double.parseDouble;            // `Double                      

class UmsatzSteuer       
 {static double hebSteuer
                 (final double prozent,final double betrag)
   {return        prozent*betrag/100.0;}
  public static void main(String[] args) //args[0],args[1] genutzt     
   {if           (args.length<2)
     {out.println("Argumente args[0], args[1] fehlen!");return;}
    final double  USt   =parseDouble(args[0]);
    double        umsatz=parseDouble(args[1]),
                  steuer=hebSteuer(USt,umsatz);
    out.printf   (    "Umsatz         =%1$8.2f EUR\r\n"
                  +"%2$4.1f  Proz. USt=%3$8.2f EUR\r\n"
                     +"Preis incl. USt=%4$8.2f EUR\r\n",
                  umsatz,USt,steuer,umsatz+steuer
                 );
   }                
 }
//****************************************************************

| Command                             %1$8.2f| FormatSpezifizierer
+---------------------------          -------+--------------------
|java UmsatzSteuer 19.0 0.55          %      | Fluchtzeichen
                                       1$    | 1. Argument umsatz  
| Output                                 8   | min. Gesamtbreite 8                        
+----------------------------             .  | Dezimal-Separator 
|Umsatz         =    0,55 EUR              2 | Präzision 2 
|19,0  Proz. USt=    0,10 EUR               f| floating point 
|Preis incl. USt=    0,65 EUR                | ohne Zehnerexponent
  Die Klasse UmsatzSteuer enthält in ihrem in geschweifte Klammern { } eingeschlossenen Klassen-Rumpf (Syntax.091) die Vereinbarung einer eigenen Methode hebSteuer(double,double), die als Eingabeparameter den Umsatzsteuer-Prozentsatz prozent und den Umsatz-Betrag betrag erwartet und als Resultatwert die Steuer hebSteuer liefert. Der Modifizierer final der Parameter bedeutet nicht, dass die entsprechenden Argumente beim aktuellen Aufruf Konstanten sein müssen, sondern dass die Parameterwerte innerhalb des Methodenrumpfs konstant bleiben.


3.2      Lokale Variablen-Vereinbarungen


  Lokale Variablen-Vereinbarungen dienen dazu, um Typ (Syntax.030) und Bezeichner (Syntax.028) für lokale Variablen im Block (Syntax .068) einzuführen, um Speicherplatz für die Werte der Variablen zu reservieren und um ggf. den Variablen-Initialisierer aufzurufen.

  Eine lokale Variablen-Vereinbarung (LocalVariableDeclaration, hier Erweiterung° durch Einsetzung von VariableModifier Syntax.070 und VariableDeclaratorList Syntax.064) ist nach Syntaxdiagramm 065 von der Form
065°:LocalVariableDeclaration     LokaleVariablenVereinbarung
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
 H   ,-----------------, -,                                     H
 H   |  ,------------, |  |                                     H
 H ->+->| Annotation |-'  |                                     H
 H   |  '------------'    |- VariableModifier                   H
 H   |-> final --,        |                                     H
 H   v           |        |                                     H
 H   |-----------'       -'                                     H
 H   |           V a r i a b l e D e c l a r a t o r L i s t    H
 H   |           ,-------------------- , <------------------,   H
 H   |           |  V  a  r i a b l e  D  e c l a r a t o r |   H
 H   |           |    Variable-                             |   H
 H   |  ,------, |  ,------------,          ,-------------, |   H
 H   '->| Type |--->| Identifier |---> = -->| Variable-   |-+-> H
 H      '------'    '------------' |        | Initializer | ^   H
 H                                 |        '-------------' |   H
 H                                 '------------------------'   H
 HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
  Als BlockStatement im Block (Syntax.068, 3.1) wird an die lokale Variablenvereinbarung noch ein Semikolon angehängt.
   z.B.
       @Deprecated double IX=3.14;      // Anmerkung (Annotation) 
       final int EAUDE=4711,COLOGNE;//COLOGNE nicht initialisiert
       double x=3.14,y;                  // y nicht initialisiert
       double steuer=hebSteuer(USt,umsatz);
       String s="Adam";                                
       String[] paar={"Adam","Eva"};
  Anmerkungen (Annotation, Syntax.100) werden in Kap. 9 besprochen. final bedeutet "konstant", d.h. die finale Variable bzw. "Konstante" erhält per Initialisierung oder per späterer Zuweisung genau einmal einen Wert zugewiesen, der nicht mehr geändert werden kann.

  Für einen skalaren (nicht Reihungs-) Typ ist ein Variablen-Initialisierer (VariableInitializer, Syntax.063) ein Ausdruck (Expression, Syntax.059). Ausdrücke werden in Kap. 4 besprochen. Reihungen werden in Kap. 6 besprochen.

3.3      System-Programmierung

  Die Abfrage einzelner System-Eigenschaften der Standard-Klasse java.lang.System ist möglich mit der Methode getProperty(String), die zu einem als String eingegebenen Namen der Eigenschaft den Wert der Eigenschaft als String ausgibt, z.B. im System (operating system) Windows XP:
          System.out.print(System.getProperty("os.name"));
                     // druckt "Windows XP"
  Das folgende Programm SystemProperty listet bei Wahl des Arguments args[0] gleich "min" eine im Programm aufgezählte Minimal -Menge von abfragbaren System-Eigenschaften auf.
  Die Auflistung aller System-Eigenschaften der Standard-Klasse java.lang.System ist möglich mit den Methoden getProperties() und list(PrintStream). Das Programm SystemProperty druckt die Liste aller abfragbaren System-Eigenschaften ( ohne Wahl eines Arguments args[0]) mit
             System.getProperties().list(System.out);
  Eine Applikation im eigenen System wird nicht gegen Sicherheitsbedingungen verstoßen. Schreibt man jedoch die Applikation um als Appplet, so wird der appletviewer oder der Browser beim Ausdruck der Liste aller System-Eigenschaften ggf. mit "security violation" (SecurityException) abbrechen. Sicherheitsüberprüfungen sind im Paket java.lang.SecurityManager zusammengestellt, Verschlüsselungsalgorithmen im Paket java.security. Die System-nahen Klassen enthalten auch in Maschinencode geschriebene Methoden mit dem Modifizierer native (Syntax.070). Die Verwendung von Maschinencode sollte den Implementatoren virtueller Java-Maschinen vorbehalten bleiben. Der normale Java-Programmierer hat genug Java-Unterstützung, um auf Maschinencode verzichten zu können.


//********************** SystemProperty.java *********************
//               Auflistung von System-Eigenschaften             *
//               Command: java SystemProperty [min]              *
//****************************************************************
//            java.lang.                              Object
import        java.util.Properties;                 // `Properties

class SystemProperty extends Properties
 {public static void main(String[] args)//optional args[0] genutzt
   {if                (args.length>0)
    {System.out.print (
     "  os.name     ="+System.getProperty(  "os.name"     )+"\r\n"
    +"  os.version  ="+System.getProperty(  "os.version"  )+"\r\n"
    +"  os.arch     ="+System.getProperty(  "os.arch"     )+"\r\n"
    +"java.version  ="+System.getProperty("java.version"  )+"\r\n"
    +"user.language ="+System.getProperty("user.language" )+"\r\n"
    +"user.country  ="+System.getProperty("user.country"  )+"\r\n"
    +" sun.arch.data"
    +        ".model="+System.getProperty( "sun.arch.data"
                                                 +".model")+"\r\n"
    +" sun.io.unicode"    
    +     ".encoding="+System.getProperty( "sun.io.unicode"
                                              +".encoding")+"\r\n"
    +"file.encoding ="+System.getProperty("file.encoding" )+"\r\n"
    +"file.separator="+System.getProperty("file.separator")+"\r\n"
    +"line.separator="
                 +(int)System.getProperty("line.separator")
                                                 .charAt(0)+" "
                 +(int)System.getProperty("line.separator")
                                                 .charAt(1)+"\r\n"
    +"path.separator="+System.getProperty("path.separator"));
    }
    else              {System.getProperties().list(System.out);}
   }
 }
//****************************************************************

| Command                                                        
+-----------------------
|java SystemProperty min

| Output                                                        
+--------------------------------------
|  os.name     =Windows XP
|  os.version  =5.1
|  os.arch     =x86
|java.version  =1.8.0_66
|user.language =de
|user.country  =DE
| sun.arch.data.model=32
| sun.io.unicode.encoding=UnicodeLittle
|file.encoding =Cp1252
|file.separator=\
|line.separator=13 10
|path.separator=;
3.4      Graphik als Applikation

  Graphikprogramme kann man nicht nur als Applet (CupApplet 1.2.2), sondern auch als Applikation schreiben. Dazu muss der Programmierer die im Applet implizit enthaltene Fenster/Rahmen-Organisation in einer Applikation selbst programmieren mit Methoden setSize (int,int), add(Component), addWindowListener(WindowAdapter), setVisible(boolean) und dispose() der Klasse java.awt.Frame.

  An die Stelle der Subklasse Applet von Component tritt die hierarchische Folge: Frame Subklasse von Window, Window Subklasse von Container und Container Subklasse von Component. Extra Aufwand erfordert das explizite "Fenster - Schließen" mit addWindowListener(WindowAdapter), Vereinbarung eines WindowAdapter und das Überschreiben der Methode windowClosing(WindowEvent).
//********************* CupApplication.java **********************
//             Graphik "Kaffeetasse" als Applikation             *
//****************************************************************
//     java.lang.                               Object
import java.awt.event.*;           // WindowEvent'||`WindowAdapter
import java.awt.*;                 //    Component'`Graphics
                                   //  Container'      
                                   //   Window'      
                                   //  Frame'
class CupApplication         
 {static int         width=636,height=width/2;      
  static Frame       f=new Frame("CupApplication");
  public static void main(String[] args)         // args ungenutzt
   {f.setFont       (new Font("SansSerif",Font.BOLD,20));
    f.setSize       (4+width+4,30+height+4);  // Component, Insets
    f.add           (new Component()                  // Container
     {public void paint(final Graphics g)   // overrides Container
       {g.drawArc   (0,-height/2,width*3/4,height*3/2,180,180);
        g.drawOval  (width*3/4,0,width  /4,height  /2);                        
        g.drawOval  (0,        0,width*3/4,height  /2);
        g.drawString(f.getInsets().toString(),width/36,height/4);
     } }            );
    f.addWindowListener(new WindowAdapter()              // Window
     {public void windowClosing(final WindowEvent e) // W.Listener
       {f.dispose   ();
        return;
     } }            );
    f.setVisible    (true);              // calls paint, Component
   }
 }
//****************************************************************

Fig.3.4.gif
Fig. 3.4: CupApplication Darstellung


  Vorteil des inzwischen verbesserten und erweiterten Pakets java.awt (abstract window toolkit) ist das einfache Design, insbesondere beim Zugriff auf die Klasse Container mit add-Befehlen. Vorteile beim "FensterSchließen" bietet das in diesem Buch nicht verwendete Paket javax.swing (Pakete.2). Java verstößt mit zwei alternativen Graphik-Paketen gegen das Prinzip des 'orthogonal design' (van Wijngaarden, ALGOL 68) für Programmiersprachen.



3.5      Testfragen

zu    Frage                                  | abdeckbare Antwort
---------------------------------------------+--------------------
                                             |
3.1   Ist es zulässig, die Argumente args[0] | ja 
     und args[1] beim Aufruf in Gänsefüßchen |
     (double quote) zu setzen ? z.B.         |
                                             |
     java Umsatzsteuer "16.0" "0.55"         |
                                             |
                                             |
3.1  Wie stellt man den Dezimal-Separator um | out.printf(
2.7  von  Komma ','  (GERMAN voreingestellt) |java.util.Locale.US,
     auf Punkt '.' (US) ?                    | "Umsatz        =%1$
                                             | ... umsatz+steuer);
                                             |
3.2     Ist die folgende eine korrekte Ver-  | ja, z.B.
      einbarung?                             |  später einmalige
                                             |  Wertzuweisung
      final int VERRUECKTUNDDREI;            | VERRUECKTUNDDREI=7;
                                             |
                                             |
3.3   Drucke mit dem Programm SystemProperty | java SystemProperty   
      die Liste aller System-Eigenschaften   |  (Liste ist
      aus.                                   |   System-abhängig)
                                             |
                                             |
3.4      Kompensiere die Graphics-Randpixel- | f.setSize(
      fehler rechts und unten!               |   4*width+1+4,
                                             |   30+heiht+1+4);
                                             |
3.4      Kann  man aus CupApplet (1.2.2) und | ja, sowohl mit
1.2.2 CupApplication (3.4)  ein "Zwitterpro- |   extends Applet, 
      gramm" Cup konstruieren, das aufrufbar |   paint(), init(),
      ist  mit  "appletviewer Cup.html"  als | als auch mit
      Applet  und mit "java Cup" als Applika-|   main()
      tion?                                  |
    Java Programmierung
  Kap.04