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
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: 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.
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?