Programmieren in Java Einführung in die (imperative) Programmierung
Name: Patrick Förster, Michael Hasseler
Programmieren in Java
Programmierung • Wunsch: Ein Zielsystem soll eine bestimmte Aktion ausführen • Zielsystem: Eine Plattform wie Windows oder MacOS oder auch ein bestimmter Prozessor • Aktion: • Addiere zwei Zahlen • Gebe einen Text auf dem Bildschirm aus • Sende Daten (an einen Drucker, über Netzwerkverbindung, ...) • ... • Problem: Wie verständigt man sich mit dem Zielsystem • Antwort: Maschinensprache
Name: Patrick Förster, Michael Hasseler
2
Programmieren in Java
Maschienencode • Ein Text geschrieben in der Sprache einer Maschine • Ein Satz in Maschinencode besteht aus Folge von Nullen und Einsen 11111010 10110011 11000000
beispielhaft
• Er beinhaltet den „Befehl“ (Opcode) sowie evtl. „Daten“ • Sätze haben eine von der Maschine abhängige Maximallänge (hier: 8 Bit (1 Bit = 0/1)) • Ein oder mehrere Sätze zusammen ergeben ein Programm • Maschinencode als Kommunikationsmittel ungeeignet: • Schwierig zu schreiben und ohne weitere Informationen schwer zu lesen • Unterschiedlicher Sprachumfang einzelner Zielsysteme • Gleiche Reihenfolge von Nullen und Einsen kann auf verschiedenen Zielsystemen zu verschiedenen Ergebnissen führen
Name: Patrick Förster, Michael Hasseler
3
Programmieren in Java
Assembler • mnemonische Symbole (Mnemonics) für mehr Lesbarkeit: movb $0x61, %al
• Mnemonic „movb“: Der hexadezimal Wert 0x61(= 97 dezimal) soll in das untere (l = low) Ende des Registers (grob: Speicherbereich) a geschoben werden • Nicht ideal, aber brauchbar • Heute noch von Bedeutung: Performance • Das Zielsystem versteht den mnemonischen Code nicht • Er muss in Maschinencode übersetzt werden • Das Übersetzungsprogramm wird „Assembler“ genannt movb $0x61, %al Assembler 10110000 01100001
Name: Patrick Förster, Michael Hasseler
Quelle: http://de.wikipedia.org/wiki/Assemblersprache
4
Programmieren in Java
Compiler • Übersetzt Code einer bestimmten Sprache in eine andere Sprache • Der ursprüngliche Programmcode: Source-Program • Der übersetzte Programmcode: Object-Program Source
Object
movb $0x61, %al
10110000 01100001
• Den Übersetzungsprozess bezeichnet man als „Compilieren“ • Der Compiler überprüft jeden Satz auf den richtigen Satzbau • Falscher Satzbau führt zu einem „Compile-Fehler“ • Nur nach erfolgreichem Compilieren, kann das Programm auf dem Zielsystem ausgeführt werden • Ausführen auf einem anderen Zielsystem ist nicht ohne weiteres möglich • Vgl. Windows-Programme MacOS-Programme • Ein Assembler ist demnach ein Compiler
Name: Patrick Förster, Michael Hasseler
5
Programmieren in Java
Interpreter • Laufzeit: Zeit, in der das Zielsystem das Object-Program ausführt • Compiler: Object-Program wird vor dem Ausführen compiliert • Interpreter: Source-Program wird zur Laufzeit analysiert, übersetzt (Object-Program) und dann ausgeführt • Nachteil: • Interpreter muss zum Ausführen mitgeliefert werden oder bereits vorhanden sein • Analyse und Übersetzen zur Laufzeit kostet eben diese • Vorteil: • Compilezeit entfällt • Interpreter eignen sich hervorragend zum „Rapid Prototyping“
Name: Patrick Förster, Michael Hasseler
6
Programmieren in Java
Übersicht Hohe Programmiersprache
Compiler
Interpreter
Maschinensprache Zielsystem
Name: Patrick Förster, Michael Hasseler
7
Programmieren in Java
„Höhere Programmiersprachen“ • • • •
Sprache, die „fast lesbar“ von Maschinensprache abstrahiert Die Anzahl solcher Sprachen ist gefühlt kaum noch aufzählbar Sprachen unterscheiden sich nicht nur in verschiedenen „Dialekten“ Verschiedene „Philosophien“: • Imperative Programmiersprachen (C, Pascal) • Objekt-orientierte Sprachen (Java, C++, Objective-C) • Funktionale Sprache (LISP, Haskell) • Deklarative Programmiersprachen (SQL) • Logische Sprachen (Prolog) • …
• Philosophien können durchaus vermischt werden!
Name: Patrick Förster, Michael Hasseler
8
Programmieren in Java
Wichtig
Ob eine Sprache compiliert oder interpretiert wird, ist kein Merkmal der Sprache!
Name: Patrick Förster, Michael Hasseler
9
Programmieren in Java
Java • • • • •
Höhere Programmiersprache Aufgebaut auf dem Paradigma der „Objektorientierten Programmierung“ Wie die meisten OOP-Sprachen aber auch imperativ Angelehnt an C++ Allerdings „schlanker“
• Version 1.0 erschien 1996 • Mit Version 1.2 (1998) sprach man von Java 2 • Version 5.0 (eigentlich 1.5) oder auch Java 5 aus dem Jahr 2004 brachte umfangreiche Änderungen, die sich bis zur Sprache selbst durchschlugen (bspw. „Generics“, „Enums“) • Die Versionen 6 (2006) und 7 (2011) brachten kleinere Erweiterungen • Version 8 (März 2014) machte mit „Closures“ wieder ein größeren Schritt in der Evolution der Sprache
Name: Patrick Förster, Michael Hasseler
10
Programmieren in Java
Bytecode • Ein Programm soll auf verschiedenen Zielsystemen lauffähig sein • Probleme: • Woher weiß man, auf welchem System das Object-Program ausgeführt werden wird? • Für jedes potentielle System müsste ein Object-Program erzeugt werden • Java-Lösung: Bytecode • Ein Java-Compiler erstellt nicht Maschinen- sondern Bytecode • Das JRE (Java Runtime Environment) ist eine „virtuelle Maschine“, die Bytecode versteht • JRE nötig um Java-Programm überhaupt ausführen zu können • Bytecode wird von der virtuellen Maschine für das jeweilige Zielsystem interpretiert
Name: Patrick Förster, Michael Hasseler
11
Programmieren in Java
Just-In-Time Compiler • Ist Java langsam, weil Bytecode interpretiert wird? • Mit Java 2 wurde der „Just-In-Time Compiler“ (HotSpot) eingeführt: • Häufig wiederkehrende Programmabschnitte werden zur Laufzeit erkannt und dann zu Maschinencode des jeweiligen Zielsystems übersetzt • Im nächsten Zyklus wird die Code-Einheit nicht mehr interpretiert, sondern der bereits fertig compilierte Maschinencode ausgeführt • Für die Code-Einheiten können zum Teil Optimierungen vorgenommen werden, zu denen normale Compilier nicht in der Lage wären (Stichworte: „Dynamische Optmierung“ oder „Closed World-Annahme“)
Name: Patrick Förster, Michael Hasseler
12
Programmieren in Java
Übersicht: Java Java Compiler JRE
Bytecode Just-In-Time
Interpreter
Maschinensprache
Name: Patrick Förster, Michael Hasseler
13
Programmieren in Java
Wichtig
Vorheriges Schaubild zeigt den „gängigen“ Java-Ansatz. In diesem wird ein Java-Programm also compiliert und interpretiert! Aber nach Folie 8: Das ist keine Eigenschaft der Sprache „Java“, sondern Konvention im Umgang mit in Java geschriebenen Code!
Name: Patrick Förster, Michael Hasseler
14
Programmieren in Java
Satzbau • Jeder Satz einer Sprache kann unterteilt werden in kleinere Bausteine • Klassische Satzlehre: Subjekt – Prädikat – Objekt • Begriffe: • Syntax: Regeln, nach denen ein beliebiger Satz Teil einer Sprache ist • Compiler/Interpreter versteht nur syntaktisch korrekte Sätze • Semantik: Bedeutung/Aussage eines Satzes der Sprache • Compiler/Interpeter kann den Sinn eines Satzes nicht feststellen • Token: Ein Baustein eines Satzes • Separator : Trennzeichen, welche die Bausteine eines Satzes separieren • Es kann bestimmte Zeichen zur Auszeichnung eines Satzendes geben • Es gibt Trennzeichen mit Semantik (z.B. Klammern in math. Ausdrücken)
Name: Patrick Förster, Michael Hasseler
15
Programmieren in Java
Token • Tokens lassen sich in die folgenden Kategorien unterteilen: • Bezeichner: Das Token besteht aus Buchstaben eines zuvor definierten Alphabets (bspw.: A-Z und 0-9) und stellt einen Name dar, dessen Bedeutung sich aus dem Kontext des Codes ergibt • Literal: Ein Literal ist ein konstanter – also unveränderbarer – Ausdruck, bspw. eine Zahl • Schlüsselwort: Schlüsselwörter sind die Pfeiler aller Sprachkonstruktionen und damit das Fundament einer Sprache • Operator: Operatoren sind Vorschriften zur Verarbeitung einer bestimmten Anzahl von Operanden (analog zur Mathematik, bspw. „+“ für die Addition zwei Zahlen) • Auch Separatoren werden zumeist als Tokens eingestuft
Name: Patrick Förster, Michael Hasseler
16
Programmieren in Java
Tokens in Java • Bezeichner: ZEICHEN=A|...|Z|a|...|z|_|$ (| == oder) ZIFFER=0|...|9 BEZEICHNER=,{ZEICHEN|ZIFFER} ({…} == optional)
myVariable my_variable myVariable_2
2_variable !&variable variable!_2
• Literale: • Boolesch (eine Ausgabe betreffend): true, false • Ganzzahlig: 1, 27, 37, 1000 • Gleitkomma: 3.1415, 2.7182 • Zeichen: 'A', '0' // Apostroph • Zeichenketten: "Hello World" // Anführungszeichen • Separatoren: ;
Satzende
{…}
Code-Block
,
Aufzählung
()
Klammerung (Operatoren, Methoden-Signatur, Methoden-Aufruf)
Name: Patrick Förster, Michael Hasseler
17
Programmieren in Java
Tokens in Java II • Schlüsselwörter: abstract
default
for
package
synchronized
assert
do
if
private
this
boolean
double
implements
protected
throw
break
else
import
public
throws
byte
enum
instanceof
return
transient
case
extends
int
short
true
catch
false
interface
static
try
char
final
long
strictfp
void
class
finally
native
super
volatile
continue
float
new
switch
while
const
Name: Patrick Förster, Michael Hasseler
goto
18
Programmieren in Java
Tokens in Java III • Operatoren: Mathematsich
Boolesch
Bitweise
=
Zuweisung
!
Negation
~
Bit-Komplement
+
Addition
==
Vergleich
Shift-Rechts
*
Multiplikation
>
Größer
>>>
" (unsigned)
/
Division
=
Größer-Gleich
|
Bit-Oder (inklusiv)
++
Inkrement