Java: Syntax-Grundlagen II Utilities Um kleine aber effiziente Applikationen in Java schreiben zu können, werden einige grundlegende Sprachelemente benötigt, deren ausführliche Erläuterung erst in Zusammenhang mit dem Wissen über das objektorientierte Konzept von Java möglich ist. Nachfolgend werden daher die wichtigsten „Nützlichkeiten“ ohne eingehende Erörterung der übergreifenden Zusammenhänge vorgestellt. • Ein- und Ausgabe Ein Programm ist i.d.R. nur dann sinnvoll, wenn die darin codierten Algorithmen auf immer neue Eingabewerte angewendet werden und entsprechende Ausgabewerte als Ergebnisse produzieren. Ein- und Ausgabe oder auch I/O für Input/Output sind Schlüsselfunktionen in jedem Programm. Wir benötigen daher Klassen und Methoden, die Zahlen oder Ziffern als Eingabewerte aufnehmen und berechnete Ergebnisse als Ausgabewerte produzieren. In Java erfolgen alle Verbindungen eines Programms nach außen über sog. Streams, das sind Datenströme oder abstrakte Datenleitungen, die nur für den Transport von Informationen zuständig sind. Die Erläuterung des vollständig objektorientierten Stream-Konzepts von Java ist im vorliegenden Rahmen jedoch zu aufwändig. Für das Einlesen und die Ausgabe von Informationen über die Eingabeaufforderung brauchen lediglich die nachfolgend aufgeführten Anweisungen übernommen und sinnvoll eingesetzt zu werden. Die bei der Nutzung jedes Datenstroms eventuell auftretenden Fehler sollten immer abgefangen werden. Auch dafür stellt Java spezielle Methoden zur Verfügung. Entweder kann eine gesamte Methode über eine throws-Anweisung abgesichert werden, oder Methodenteile, die I/O-Funktionen enthalten, werden in try...catch-Blöcke unterteilt. Die in Java bereitgestellten Klassen und Methoden für die Ein- und Ausgabe befinden sich im Paket java.io, das zu Beginn jedes Programms über folgende Anweisung importiert werden muss import java.io.*; Damit können im folgenden die Standard-Datenströme für die Eingabe über Tastatur sowie für die Ausgabe und für Fehlermeldungen im Fenster der Eingabeaufforderung gelenkt werden. © Prof. Dr.-Ing. Gudrun Breitzke Grundlagen Java-Syntax II - 1 Eingabe Für das Einlesen von Werten in der Eingabeaufforderung über die Tastatur wird der Standard-Input-Stream System.in genutzt. Die Klasse InputStream stellt dabei Methoden zur Verfügung, mit denen der Byte-Stream in die erwarteten Werte umgeleitet werden kann. Für das Einlesen der bekannten Zahlen-Datentypen stehen innerhalb des Filterstroms BufferedReader statische Methoden zur Verfügung, die im vorliegenden Fall wie folgt eingesetzt werden: Byte.parseByte(name.readLine()) Integer.parseInt(name.readLine()) Long.parseLong(name.readLine()) Float.parseFloat(name.readLine()) Double.parseDouble(name.readLine()) Das folgende kleine Programm "InOut_01.java" zeigt die komplette Anwendung der Methoden anhand eines Beispiels auf, in dem eine Integer- und eine Fließkommazahl eingelesen werden und das Ergebnis ihrer Multiplikation – im Vorgriff aus den folgenden Abschnitt – ausgegeben wird. Die für die Ein- und Ausgabe notwendigen Programmteile sind in Fettschrift hervorgehoben: import java.io.*; public class InOut_01 { public static void main(String[] args) throws IOException // Hiermit wird die gesamte Methode gegen // eine IOException abgesichert { /* Nutzung des Standard-Input-Streams "System.in" * per Filter-Stream "BufferedReader" * Der elementare Datenstrom der Eingabekonsole * "InputStreamReader" wird mit "BufferedReader" verschachtelt, * die eingegebenen Werte werden gepuffert */ BufferedReader eingabe = new BufferedReader( new InputStreamReader(System.in)); int n; float x; // Ausgabe der Eingabeaufforderungen und Einlesen von n und x System.out.print("\nBitte geben Sie eine ganze Zahl ein: "); n = Integer.parseInt(eingabe.readLine()); System.out.print("Bitte geben Sie eine Fliesskommazahl ein: "); x = Float.parseFloat(eingabe.readLine()); x = x*n; System.out.println ("\nDie beiden Zahlen ergeben in der Multiplikation " + x); } } © Prof. Dr.-Ing. Gudrun Breitzke Grundlagen Java-Syntax II - 2 In der Eingabeaufforderung ergibt sich damit z.B. folgender Programmablauf C:\daten>java InOut_01 Bitte geben Sie eine ganze Zahl ein: 4 Bitte geben Sie eine Fliesskommazahl ein: 1.234 Die beiden Zahlen ergeben in der Multipliktion 4.936 C:\daten> Ausgabe Für die Ausgabe im Fenster der Eingabeaufforderung wird der Standard-OutputStream System.out genutzt. Werte und Texte können darin auf sehr einfache Weise über die folgenden beiden Anweisungen ausgegeben werden: System.out.print ("Text"); System.out.println ("Text"); Die beiden Anweisungen unterscheiden sich darin, dass nach Anwendung von ".println" ein Zeilenumbruch erfolgt, siehe auch das vorangegangene und nachfolgende Programmbeispiel. Auszugebender Text wird in Hochkommata eingeschlossen, eine Steuerung der Ausgabe kann dabei über Escape-Sequenzen erfolgen, z.B. "\n" für einen zusätzlichen Zeilenumbruch. Wenn in einer Ausgabeanweisung Text und Variablenwerte oder Berechnungsergebnisse ausgegeben werden sollen, müssen sie über den Operator + miteinander verknüpft werden. Nachfolgend wird das o.a. Beispiel dahingehend umgewandelt, dass die beiden eingelesenen Zahlen nicht multipliziert sondern addiert werden. Im folgenden Quellcode wird die Ausgabe dieser Addition zudem in die println-Anweisung geschrieben – und zwar einmal "korrekt", indem die Addition in Klammern gesetzt wird und ihr Ergebnis somit mit der Textausgabe verknüpft wird, und danach "falsch", indem die beiden Variablenwerte ohne Klammern angegeben werden, der Operator + bewirkt dadurch nur die Ausgabe-Verknüpfung und nicht die Addition: © Prof. Dr.-Ing. Gudrun Breitzke Grundlagen Java-Syntax II - 3 import java.io.*; public class InOut_02 { public static void main(String[] args) throws IOException {BufferedReader eingabe = new BufferedReader( new InputStreamReader(System.in)); int n; float x; System.out.print("\nBitte geben Sie eine ganze Zahl ein: "); n = Integer.parseInt(eingabe.readLine()); System.out.print("Bitte geben Sie eine Fliesskommazahl ein: "); x = Float.parseFloat(eingabe.readLine()); System.out.println ("\nDie beiden Zahlen ergeben in der Addition "+(x+n)); System.out.println ("\nDie beiden Zahlen ergeben in der Addition "+x+n); } } In der Eingabeaufforderung ergibt sich damit z.B. folgender Programmablauf: C:\daten>java InOut_02 Bitte geben Sie eine ganze Zahl ein: 4 Bitte geben Sie eine Fliesskommazahl ein: 1.234 Die beiden Zahlen ergeben in der Addition 5.234 Die beiden Zahlen ergeben in der Addition 1.2344 C:\daten> © Prof. Dr.-Ing. Gudrun Breitzke Grundlagen Java-Syntax II - 4 • Methoden für Mathematische Operationen Die Klasse Math enthält Methoden zur Fließkommazahlen-Arithmetik. Sie ist Bestandteil des Standardpakets java.lang und braucht daher nicht explizit importiert zu werden. Die für uns wichtigsten Methoden werden nachfolgend ohne ihren jeweiligen Modifikator aufgelistet, ihr Gebrauch wird nachfolgend anhand eines Programmbeispiels erläutert. Der Datentyp des Rückgabewertes und der Argumente ist jeweils angegeben: Arithmetik double pow (double x, double y) xy → Beispiel: Math.pow(2,4) liefert 16.0 double sqrt (double x) Quadratwurzel aus x → Beispiel: Math.sqrt(81) liefert 9.0 double exp (double x) Exponentialwert zur Basis e → Beispiel: Math.exp(0) liefert 1.0 double log (double x) Natürlicher Logarithmus (Basis e) → Beispiel: Math.log(1) liefert 0.0 double random () Pseudo-Zufallszahl zwischen 0 und 1.0 Mathematische Konstanten PI E → → π e Winkelfunktionen double sin (double x) double cos (double x) double tan (double x) Trigonometrischer Sinus, Cosinus und Tangens im Bogenmaß → Beispiel: Math.sin(90) liefert 0.8939966636005579 Math.sin(90*Math.PI/180) liefert 1.0 © Prof. Dr.-Ing. Gudrun Breitzke Grundlagen Java-Syntax II - 5 double asin (double x) double acos (double x) double atan (double x) Arkus-Sinus (Wertebereich -π/2 ÷ +π/2), Arkus-Cosinus (Wertebereich 0 ÷ π) und Arkus-Tangens (Wertebereich -π/2 ÷ +π/2) im Bogenmaß → Beispiel: Math.acos(0.5) liefert 1.0471975511965979 Math.acos(0.5)*180/Math.PI liefert 60.0 double toRadians (double x) double toDegrees (double x) Konvertiert einen Gradwert in's Bogenmaß und umgekehrt → Beispiel: Math.toRadians(180) liefert 3.141592653589793 Math.toDegrees(Math.PI/2) liefert 90.0 Im folgenden kleinen Programmbeispiel namens Hypothenuse.java wird die Hypothenusenlänge eines rechtwinkligen Dreiecks berechnet, dessen Kathetenlängen a und b einzugeben sind: c = a2 + b2 public class Hypothenuse { public static void main(String[] args) throws IOException { BufferedReader eingabe = new BufferedReader( new InputStreamReader(System.in)); double a,b,c; System.out.println("\n* Es wird die Laenge der Hypothenuse *"); System.out.println("* eines rechtwinkligen Dreiecks *"); System.out.println("* mit den Katheten a und b berechnet *\n"); System.out.print("Bitte geben Sie die Laenge von a: "); a = Double.parseDouble(eingabe.readLine()); System.out.print("Bitte geben Sie die Laenge von b: "); b = Double.parseDouble(eingabe.readLine()); c=Math.sqrt(Math.pow(a,2)+Math.pow(b,2)); System.out.println( "\nDie Laenge der Hypothenuse c betraegt " +c+"\n"); } } Anmerkung: Bei der einfachen Quadratur eines Wertes ist natürlich die einfachere Schreibweise, die Variable mit sich selbst zu multiplizieren, anstatt den Methodenaufruf zu wählen. Die oben fett markierte Zeile könnte also auch wie folgt codiert werden: c=Math.sqrt(a*a+b*b); © Prof. Dr.-Ing. Gudrun Breitzke Grundlagen Java-Syntax II - 6