Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Komponenten, JavaBeans und Module
14 Die Klassenbibliothek
15 Einführung in die nebenläufige Programmierung
16 Einführung in Datenstrukturen und Algorithmen
17 Einführung in grafische Oberflächen
18 Einführung in Dateien und Datenströme
19 Einführung ins Datenbankmanagement mit JDBC
20 Einführung in <XML>
21 Testen mit JUnit
22 Bits und Bytes und Mathematisches
23 Die Werkzeuge des JDK
A Java SE-Paketübersicht
Stichwortverzeichnis


Download:

- Beispielprogramme, ca. 35,4 MB


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil 1 Java ist auch eine Sprache
Pfeil 1.1 Historischer Hintergrund
Pfeil 1.2 Warum Java gut ist – die zentralen Eigenschaften
Pfeil 1.2.1 Bytecode
Pfeil 1.2.2 Ausführung des Bytecodes durch eine virtuelle Maschine
Pfeil 1.2.3 Plattformunabhängigkeit
Pfeil 1.2.4 Java als Sprache, Laufzeitumgebung und Standardbibliothek
Pfeil 1.2.5 Objektorientierung in Java
Pfeil 1.2.6 Java ist verbreitet und bekannt
Pfeil 1.2.7 Java ist schnell – Optimierung und Just-in-time-Compilation
Pfeil 1.2.8 Das Java-Security-Modell
Pfeil 1.2.9 Zeiger und Referenzen
Pfeil 1.2.10 Bring den Müll raus, Garbage-Collector!
Pfeil 1.2.11 Ausnahmebehandlung
Pfeil 1.2.12 Angebot an Bibliotheken und Werkzeugen
Pfeil 1.2.13 Einfache Syntax der Programmiersprache Java
Pfeil 1.2.14 Java ist Open Source
Pfeil 1.2.15 Wofür sich Java weniger eignet
Pfeil 1.2.16 Java im Vergleich zu anderen Sprachen *
Pfeil 1.2.17 Java und das Web, Applets und JavaFX
Pfeil 1.2.18 Features, Enhancements (Erweiterungen) und ein JSR
Pfeil 1.2.19 Die Entwicklung von Java und seine Zukunftsaussichten
Pfeil 1.3 Java-Plattformen: Java SE, Java EE, Java ME und Java Card
Pfeil 1.3.1 Die Java SE-Plattform
Pfeil 1.3.2 Java für die Kleinen
Pfeil 1.3.3 Java für die ganz, ganz Kleinen
Pfeil 1.3.4 Java für die Großen
Pfeil 1.3.5 Echtzeit-Java (Real-time Java)
Pfeil 1.4 Die Installation der Java Platform, Standard Edition (Java SE)
Pfeil 1.4.1 Die Java SE von Oracle
Pfeil 1.4.2 Download des JDK
Pfeil 1.4.3 Java SE unter Windows installieren
Pfeil 1.4.4 JDK/JRE deinstallieren
Pfeil 1.4.5 JDK unter Linux installieren
Pfeil 1.4.6 JDK unter Max OS X installieren
Pfeil 1.5 Das erste Programm compilieren und testen
Pfeil 1.5.1 Compilertest
Pfeil 1.5.2 Ein Quadratzahlen-Programm
Pfeil 1.5.3 Der Compilerlauf
Pfeil 1.5.4 Die Laufzeitumgebung
Pfeil 1.5.5 Häufige Compiler- und Interpreter-Probleme
Pfeil 1.6 Entwicklungsumgebungen im Allgemeinen
Pfeil 1.6.1 Die Entwicklungsumgebung Eclipse
Pfeil 1.6.2 NetBeans von Oracle
Pfeil 1.6.3 IntelliJ IDEA
Pfeil 1.6.4 Ein Wort zu Microsoft, Java und zu J++, J#
Pfeil 1.7 Eclipse im Speziellen
Pfeil 1.7.1 Eclipse entpacken und starten
Pfeil 1.7.2 Das erste Projekt anlegen
Pfeil 1.7.3 Verzeichnisstruktur für Java-Projekte *
Pfeil 1.7.4 Eine Klasse hinzufügen
Pfeil 1.7.5 Übersetzen und ausführen
Pfeil 1.7.6 Projekt einfügen, Workspace für die Programme wechseln
Pfeil 1.7.7 Plugins für Eclipse
Pfeil 1.8 NetBeans im Speziellen
Pfeil 1.8.1 NetBeans-Bundles
Pfeil 1.8.2 NetBeans installieren
Pfeil 1.8.3 NetBeans starten
Pfeil 1.8.4 Ein neues NetBeans-Projekt anlegen
Pfeil 1.8.5 Ein Java-Programm starten
Pfeil 1.9 Zum Weiterlesen
 

Zum Seitenanfang

1.2Warum Java gut ist – die zentralen Eigenschaften Zur vorigen ÜberschriftZur nächsten Überschrift

Java ist eine objektorientierte Programmiersprache, die sich durch einige zentrale Eigenschaften auszeichnet. Diese machen sie universell einsetzbar und für die Industrie als robuste Programmiersprache interessant. Da Java objektorientiertes Programmieren ermöglicht, können Entwickler moderne und wiederverwertbare Softwarekomponenten programmieren.

Zum Teil wirkt Java sehr konservativ, aber das liegt daran, dass die Sprachdesigner nicht alles das sofort einbauen, was im Moment gerade hipp ist (XML-Literale sind so ein Beispiel). Java nahm schon immer das, was sich in anderen Programmiersprachen als sinnvoll und gut herausgestellt hat, in den Sprachkern auf, vermied es aber, Dinge aufzunehmen, die nur von sehr wenigen Entwicklern eingesetzt werden oder die öfter zu Fehlern führen. In den Anfängen stand C++ als Vorbild da, heute schielt Java auf C# und Skriptsprachen.

Einige der zentralen Eigenschaften wollen wir uns im Folgenden anschauen und dabei auch zentrale Begriffe und Funktionsweisen beleuchten.

 

Zum Seitenanfang

1.2.1Bytecode Zur vorigen ÜberschriftZur nächsten Überschrift

Zunächst ist Java eine Programmiersprache wie jede andere. Doch im Gegensatz zu herkömmlichen Übersetzern einer Programmiersprache, die in der Regel Maschinencode für einen bestimmten Prozessor (zum Beispiel für x86er-Mikroprozessoren oder Prozessoren der ARM-Architektur) und einer spezielle Plattform (etwa Linux oder Windows) generieren, erzeugt der Java-Compiler aus den Quellcode-Dateien binären Programmcode, den so genannten Bytecode, für eine virtuelle Maschine. Bytecode ist vergleichbar mit Mikroprozessorcode für einen erdachten Prozessor, der Anweisungen wie arithmetische Operationen, Sprünge und Weiteres kennt.

 

Zum Seitenanfang

1.2.2Ausführung des Bytecodes durch eine virtuelle Maschine Zur vorigen ÜberschriftZur nächsten Überschrift

Damit der Programmcode des virtuellen Prozessors ausgeführt werden kann, kümmert sich nach der Übersetzungsphase von Programmcode in Bytecode eine Laufzeitumgebung, genannt die Java Virtual Machine (JVM), um den Bytecode.[ 8 ](Die Idee des Bytecodes (das Satzprogramm FrameMaker schlägt hier als Korrektur »Bote Gottes« vor) ist schon alt. Die Firma Datapoint schuf um 1970 die Programmiersprache PL/B, die Programme auf Bytecode abbildet. Auch verwendet die Originalimplementierung von UCSD-Pascal, die etwa Anfang 1980 entstand, einen Zwischencode – kurz p-code. ) Die Laufzeitumgebung (auch Runtime-Interpreter genannt), lädt den Bytecode, prüft ihn und führt ihn in einer kontrollierten Umgebung aus. Die JVM bietet eine ganze Reihe von Zusatzdiensten wie eine automatische Speicherbereinigung (Garbage-Collector), die Speicher aufräumt, sowie eine starke Typprüfung unter einem klar definierten Speicher- und Threading-Modell.

Es gibt unterschiedliche virtuelle Maschinen verschiedener Hersteller. Die wichtigste ist die JVM im Oracle JDK – kurz JDK – bzw. im OpenJDK. Die JVM ist frei und für Windows, Linux und Solaris erhältlich. Hersteller eigener Betriebssysteme wie IBM oder HP haben eigene Java-Laufzeitumgebungen, und auch Apple pflegte lange Zeit eine komplett eigene JVM, bis Apple den Code an Oracle für das OpenJDK übergab. Auch Google setzt bei Android neuerdings auf das OpenJDK. Außerdem gibt es quelloffene JVMs, die zum Teil aus akademischen Arbeiten entstanden sind. Eine virtuelle Maschine selbst ist in der Regel in C oder C++ programmiert, genauso wie einige Bibliotheken, und hat eine nicht zu unterschätzende Komplexität.

Java on a chip

Neben einer Laufzeitumgebung, die den Java-Bytecode interpretiert und in den Maschinencode eines Wirtssystems übersetzt, wurde auch ein Prozessor konstruiert, der in der Hardware Bytecode ausführt. Die Entwicklung ging damals verstärkt von Sun aus, und einer der ersten Prozessoren war PicoJava. Bei der Entwicklung des Prozessors stand nicht die maximale Geschwindigkeit im Vordergrund, sondern die Kosten pro Chip, um ihn in jedes Haushaltsgerät einbauen zu können. Das Interesse an Java auf einem Chip zieht nun nach einer Flaute wieder an, denn viele mobile Endgeräte müssen mit schnellen Ausführungseinheiten versorgt werden.

Die ARM-Technologie des Unternehmens ARM Limited erlaubt durch Jazelle DBX eine sehr schnelle Ausführung von Java-Bytecode. Mit dem Prozessor S5L8900 hat Samsung die ARM-Technologie ARM1176JZ(F)-S zusammen mit Speicherschnittstellen und Teilen für Connectivity, Peripherie und Multimedia-Möglichkeiten in Silizium gegossen, und als 667-MHz-Prozessor sitzt er nun in Apples iPhone. Die Ironie des Schicksals ist dabei, dass Apple im iPhone bisher keine Java-Unterstützung vorsieht.

Der aJ-102 und aJ-200 von aJile Systems Inc. sind weitere Prozessoren, die Java-Bytecode direkt ausführen; der aJ-200 unterstützt auch direktes Threading. Und wenn wir den Pressemitteilungen von Azul Systems[ 9 ](http://www.azulsystems.com) glauben können, gibt es auch bald einen 64-Bit-Prozessor mit 48 Kernen, der Java- und auch .NET-Bytecode ausführt. Ein Doppelherz tut auch Java gut.

 

Zum Seitenanfang

1.2.3Plattformunabhängigkeit Zur vorigen ÜberschriftZur nächsten Überschrift

Eine zentrale Eigenschaft von Java ist seine Plattformunabhängigkeit bzw. Betriebssystemunabhängigkeit. Diese wird durch zwei zentrale Konzepte erreicht: Zum einen bindet sich Java nicht an einen bestimmten Prozessor oder eine bestimmte Architektur, sondern der Compiler generiert Bytecode, den eine Laufzeitumgebung dann abarbeitet. Zum anderen abstrahiert Java von den Eigenschaften eines konkreten Betriebssystems, schafft etwa eine Schnittstelle zum Ein-/Ausgabesystem oder eine API für grafische Oberflächen. Entwickler programmieren immer gegen eine Java-API, aber nie gegen die API der konkreten Plattform, etwa die Windows- oder Unix-API. Die Java-Laufzeitumgebung bildet Aufrufe etwa auf Dateien für das jeweilige System ab, ist also Vermittler zwischen den Java-Programmen und der eigentlichen Betriebssystem-API.

Zwar ist das Konzept einer plattformneutralen Programmiersprache schon recht alt, doch erst in den letzten zehn Jahren kamen mehr und mehr Programmiersprachen hinzu. Neben Java sind plattformunabhängige Programmiersprachen und Laufzeitumgebungen .NET-Sprachen wie C# auf der CLR (Common Language Runtime – entspricht der Java VM), Perl, Python oder Ruby. Plattformunabhängigkeit ist schwer, denn die Programmiersprache und ein Bytecode produzierender Compiler sind nur ein Teil – der größere Teil sind die Laufzeitumgebung und eine umfangreiche API. Zwar ist auch C an sich eine portable Sprache, und ANSI-C-Programme lassen sich von jedem C-Compiler auf jedem Betriebssystem mit Compiler übersetzen, aber das Problem sind die Bibliotheken, die über ein paar simple Dateioperationen nicht hinauskommen.

In Java 7 änderte sich die Richtung etwas, was sich besonders an der neuen API für die Dateisystemunterstützung ablesen lässt. Vor Java 7 war die Datei-Klasse so aufgebaut, dass die Semantik gewisser Operationen nicht ganz genau spezifiziert war und auf diese Weise sehr plattformabhängig war. Es gibt aber in der Datei-Klasse keine Operation, die nur auf einer Plattform zur Verfügung steht und andere Plattformen ausschließt. Das Credo lautete immer: Was nicht auf allen Plattformen existiert, kommt nicht in die Bibliothek.[ 10 ](Es gibt sie durchaus, die Methoden, die zum Beispiel nur unter Windows zur Verfügung stehen. Aber dann liegen sie nicht in einem java- oder javax-Paket, sondern in einem internen Paket. ) Mit Java 7 gab es einen Wechsel: Nun sind plattformspezifische Dateieigenschaften zugänglich. Es bleibt abzuwarten, ob in Zukunft in anderen API-Bereichen – vielleicht bei grafischen Oberflächen – noch weitere Beispiele hinzukommen.

 

Zum Seitenanfang

1.2.4Java als Sprache, Laufzeitumgebung und Standardbibliothek Zur vorigen ÜberschriftZur nächsten Überschrift

Java ist nicht nur eine Programmiersprache, sondern ebenso ein Laufzeitsystem, was Oracle durch den Begriff »Java Platform« klarstellen will. So gibt es neben der Programmiersprache Java durchaus andere Sprachen, die eine Java-Laufzeitumgebung ausführen, etwa diverse Skriptsprachen wie Groovy (http://groovy.codehaus.org), JRuby (http://jruby.org), Jython (http://www.jython.org) oder Scala (http://www.scala-lang.org). Skriptsprachen auf der Java-Plattform werden immer populärer; sie etablieren eine andere Syntax, nutzen aber die JVM und die Bibliotheken.

Zu der Programmiersprache und JVM kommt ein Satz von Standardbibliotheken für Datenstrukturen, Zeichenkettenverarbeitung, Datum-/Zeit-Verarbeitung, grafische Oberflächen, Ein-/Ausgabe, Netzwerkoperationen und mehr. Das bildet die Basis für höherwertige Dienste wie Datenbankanbindungen oder Web-Services. Integraler Bestandteil der Standardbibliothek seit Java 1.0 sind weiterhin Threads. Sie sind leicht zu erzeugende Ausführungsstränge, die unabhängig voneinander arbeiten können. Mittlerweile unterstützen alle populären Betriebssysteme diese »leichtgewichtigen Prozesse« von Haus aus, sodass die JVM diese parallelen Programmteile nicht nachbilden muss, sondern auf das Betriebssystem verweisen kann. Bei den neuen Multi-Core-Prozessoren sorgt das Betriebssystem für eine optimale Ausnutzung der Rechenleistung, da Threads wirklich nebenläufig arbeiten können.

 

Zum Seitenanfang

1.2.5Objektorientierung in Java Zur vorigen ÜberschriftZur nächsten Überschrift

Java ist als Sprache entworfen worden, die es einfach machen sollte, große, fehlerfreie Anwendungen zu schreiben. In C-Programmen erwartet uns statistisch gesehen alle 55 Programmzeilen ein Fehler. Selbst in großen Softwarepaketen (ab einer Million Codezeilen) findet sich, unabhängig von der zugrunde liegenden Programmiersprache, im Schnitt alle 200 Programmzeilen ein Fehler. Selbstverständlich gilt es, diese Fehler zu beheben, obwohl bis heute noch keine umfassende Strategie für die Softwareentwicklung im Großen gefunden wurde. Viele Arbeiten der Informatik beschäftigen sich mit der Frage, wie Tausende Programmierer über Jahrzehnte miteinander arbeiten und Software entwerfen können. Dieses Problem ist nicht einfach zu lösen und wurde im Zuge der Softwarekrise Mitte der 1960er Jahre heftig diskutiert.

Eine Laufzeitumgebung eliminiert viele Probleme technischer Natur. Objektorientierte Programmierung versucht, die Komplexität des Softwareproblems besser zu modellieren. Die Philosophie ist, dass Menschen objektorientiert denken und eine Programmierumgebung diese menschliche Denkweise abbilden sollte. Genauso wie Objekte in der realen Welt verbunden sind und kommunizieren, muss es auch in der Softwarewelt möglich sein. Objekte bestehen aus Eigenschaften; das sind Dinge, die ein Objekt »hat« und »kann«. Ein Auto »hat« Räder und einen Sitz und »kann« beschleunigen und bremsen. Objekte entstehen aus Klassen, das sind Beschreibungen für den Aufbau von Objekten.

Die Sprache Java ist nicht bis zur letzten Konsequenz objektorientiert, so wie Smalltalk es vorbildlich demonstriert. Primitive Datentypen wie Ganzzahlen oder Unicode-Zeichen werden nicht als Objekte verwaltet. Als Grund für dieses Design wird genannt, dass der Compiler und die Laufzeitumgebung mit der Trennung besser in der Lage waren, die Programme zu optimieren. Allerdings zeigt die virtuelle Maschine von Microsoft für die .NET-Plattform und andere moderne Programmiersprachen, dass auch ohne die Trennung eine gute Performance möglich ist.

 

Zum Seitenanfang

1.2.6Java ist verbreitet und bekannt Zur vorigen ÜberschriftZur nächsten Überschrift

Unabhängig von der Leistungsfähigkeit einer Sprache zählen am Ende doch nur betriebswirtschaftliche Faktoren: Wie schnell und billig lässt sich ein vom Kunden gewünschtes System bauen, und wie stabil und änderungsfreundlich ist es? Dazu kommen Fragen wie: Wie sieht der Literaturmarkt aus, wie die Ausbildungswege, woher bekommt ein Team einen Entwickler oder Consultant, wenn es brennt? Dies sind nicht unbedingt Punkte, die Informatiker beim Sprachvergleich an die erste Stelle setzen, sie sind aber letztendlich für den Erfolg einer Softwareplattform entscheidend. Fast jede Universität lehrt Java, und mit Java ist ein Job sicher. Konferenzen stellen neue Trends vor und schaffen Trends. Diese Kette ist nicht zu durchbrechen, und selbst wenn heute eine neue Supersprache mit dem Namen »Bali« auftauchen würde, würde es Jahre dauern, bis ein vergleichbares System geschaffen wäre. Wohlgemerkt: Das sagt nichts über die Innovations- oder Leistungsfähigkeit aus, nur über die Marktsättigung, aber dadurch wird Java eben für so viele interessant.

Heute ist Java die Basis sehr erfolgreicher Produkte, viele auf der Serverseite. Dazu zählen Facebook, LinkedIn, Twitter, Amazon, eBay. Auf der Client-Seite ist Java seltener zu finden, das Spiel Minecraft ist eher eine Ausnahme.

Java-Entwickler sind glücklich

Andrew Vos hat sich Kommentare angeschaut, mit denen Entwickler ihre Programme in die Versionsverwaltung einpflegen.[ 11 ](http://tutego.de/go/profanity) Dabei zählte er, wie viele »böse« Wörter wie »shit«, »omg«, »wtf« beim Check-in vorkommen. Seine Herangehensweise ist zwar statistisch nicht ganz ordentlich, aber bei seinen untersuchten Projekten stehen Java-Entwickler recht gut da und haben wenig zu fluchen. Die Kommentare sind amüsant zu lesen und geben unterschiedliche Erklärungen, etwa dass JavaScript-Programmierer eigentlich nur über den IE fluchen, aber nicht über die Sprache JavaScript an sich und dass Python-Programmierer zum Fluchen zu anständig sind.

 

Zum Seitenanfang

1.2.7Java ist schnell – Optimierung und Just-in-time-Compilation Zur vorigen ÜberschriftZur nächsten Überschrift

Die Laufzeitumgebung von Java 1.0 s tartete mit einer puren Interpretation des Bytecodes. Das bereitete massive Geschwindigkeitsprobleme, denn beim Interpretieren muss die Arbeit eines Prozessors – das Erkennen, Dekodieren und Ausführen eines Befehls – noch einmal in Software wiederholt werden; das kostet viel Zeit. Java-Programme der ersten Stunde waren daher deutlich langsamer als übersetzte C(++)-Programme und brachten Java den Ruf ein, eine langsame Sprache zu sein.

Die Technik der Just-in-time-(JIT-)Compiler[ 12 ](Diese Idee ist auch schon alt: HP hatte um 1970 JIT-Compiler für BASIC-Maschinen. ) war der erste Schritt, das Problem anzugehen. Ein JIT-Compiler beschleunigt die Ausführung der Programme, indem er zur Laufzeit den Bytecode, also die Programmanweisungen der virtuellen Maschine, in Maschinencode der jeweiligen Plattform übersetzt. Anschließend steht ein an die Architektur angepasstes Programm im Speicher, das der physikalische Prozessor ohne Interpretation schnell ausführt. Mit dieser Technik entspricht die Geschwindigkeit der von anderen übersetzten Sprachen. Jedoch übersetzt ein guter JIT nicht alles, sondern versucht über diverse Heuristiken herauszufinden, ob sich eine Übersetzung – die ja selbst Zeit kostet – überhaupt lohnt. Die JVM beginnt daher immer mit einer Interpretation und wechselt dann in einen Compiler-Modus, wenn es nötig wird. Somit ist Java im Grunde eine compilierte, aber auch interpretierte Programmiersprache – von der Ausführung durch Hardware einmal abgesehen. Vermutlich ist der Java-Compiler in der JVM der am häufigsten laufende Compiler überhaupt. Und das Ergebnis ist sehr gut, wie sich Java im Vergleich zu anderen Sprachen schlägt.[ 13 ](http://benchmarksgame.alioth.debian.org/u64q/which-programs-are-fastest.php)

Der JIT-Compiler von Sun wurde immer besser und entwickelte sich weiter zu einer Familie von virtuellen Maschinen, die heute unter dem Namen HotSpot bekannt sind. Das Besondere ist, dass HotSpot die Ausführung zur Laufzeit überwacht und »heiße« (sprich kritische) Stellen findet, etwa Schleifen mit vielen Wiederholungen – daher auch der Name »HotSpot«. Daraufhin steuert die JVM ganz gezielt Übersetzungen und Optimierungen. Zu den Optimierungen gehören Klassiker, wie das Zusammenfassen von Ausdrücken, aber auch viele dynamische Optimierungen fallen in diesen Bereich, zu denen ein statischer C++-Compiler nicht in der Lage wäre, weil ihm der Kontext fehlt.[ 14 ](Dynamische Methodenaufrufe sind in der Regel sehr schnell, weil die JVM die Hierarchie kennt. ) Zudem kann die JVM Bytecode zu jeder Zeit nachladen, der wie alle schon geladenen Teile genauso optimiert wird. Der neu eingeführte Programmcode kann sogar alte Optimierungen und Maschinencode ungültig machen, den dann die JVM neu übersetzt.

HotSpot steht genauso wie das Laufzeitsystem unter der freien GPL-Lizenz und ist für jeden einsehbar. Die JVM ist hauptsächlich in C++ programmiert, aber aus Performance-Gründen befinden sich dort auch Teile in Maschinencode, was die Portierung nicht ganz einfach macht. Das Zero-Assembler Project (http://openjdk.java.net/projects/zero) hat sich zum Ziel gesetzt, HotSpot ohne Maschinencode zu realisieren, sodass eine Portierung einfach ist. Seit dem JDK 1.6.0_04-b12, das Ende 2007 veröffentlicht wurde, hat die HotSpot-VM eine eigene Entwicklung und Versionsnummer.

Traditioneller Compiler und Java-Compiler mit Laufzeitumgebung

Abbildung 1.2Traditioneller Compiler und Java-Compiler mit Laufzeitumgebung

 

Zum Seitenanfang

1.2.8Das Java-Security-Modell Zur vorigen ÜberschriftZur nächsten Überschrift

Das Java-Security-Modell gewährleistet den sicheren Programmablauf auf den verschiedensten Ebenen. Der Verifier liest Code und überprüft die strukturelle Korrektheit und Typsicherheit. Weist der Bytecode schon Fehler auf, kommt der Programmcode erst gar nicht zur Ausführung. Die Prüfung ist wichtig, denn ein Klassenlader (engl. class loader) kann Klassendateien von überall her laden. Während vielleicht dem Bytecode aus dem lokalen Laufwerk vertraut werden kann, gilt das mitunter nicht für Code, der über ein ungesichertes Netzwerk übertragen wurde, wo ein Dritter plötzlich Schadcode einfügt (Man-in-the-Middle-Angriff). Ist der Bytecode korrekt in der virtuellen Maschine angemeldet, folgen weitere Prüfungen. So sind etwa (mit entsprechender Anpassung) keine Lese-/Schreibzugriffe auf private Variablen möglich. Treten Sicherheitsprobleme auf, werden sie durch Exceptions zur Laufzeit gemeldet – so kommt es etwa zu keinen Pufferüberläufen. Auf der Programmebene überwacht ein Security-Manager Zugriffe auf das Dateisystem, die Netzwerk-Ports, externe Prozesse und weitere Systemressourcen. Das Sicherheitsmodell kann vom Programmierer erweitert und über Konfigurationsdateien einfach konfiguriert werden.

Java kämpfte Anfang 2013 mit einigen bösen Sicherheitsproblemen. Applets, also Java-Programme, die in Webseiten eingebettet sind, konnten sich Zugriff zum System verschaffen, Anwendungen starten und so Blödsinn anstellen. Die Debatte kochte so hoch, dass auch Massenmedien[ 15 ](Ja, selbst in der BILD-Zeitung ist es angekommen: http://www.bild.de/digital/internet/datenschutz/java-sicherheitsluecke-25899768.bild.html. ) die Meldung aufgriffen und zur Deinstallation von Java rieten. Zwei Dinge müssen jedoch berücksichtigt werden: Erstens betraf das Problem nur Applets, die fast vollständig aus dem Netz verschwunden sind (bis auf ELSTER[ 16 ](Siehe http://www.elster.de, das es ermöglicht, »verschiedene Steuererklärungen elektronisch via Internet an das Finanzamt zu übermitteln«. ), das uns immer noch zu Java zwingt). Auf der Serverseite, wo Java in der Regel zu Hause ist, gefährden diese Angriffe die Sicherheit nicht. Zweitens – allerdings ist das kein wirklicher Trost[ 17 ](Und die Frage ist auch, was peinlicher ist: gegen eine gut gemachte Attacke schwach zu werden oder bei der Eingabe von »File:///« im Editor mit Rechtschreibkorrektur abzustürzen. ) – kann es durch Programmierfehler der Sandbox immer wieder zu Ausbrüchen aus der Umgebung kommen. Vergleichbare Meldungen vom Acrobat Reader, der einbettete Skripte ausführt, sind nicht selten. Da ist es gut, dass Java eine so hohe Verbreitung hat, dass Fehler schnell gefunden und gefixt werden. Leider machte Oracle hier aber keine sehr gute Figur, und es dauerte eine paar Tage, bis der gefährliche Zero-Day-Exploit[ 18 ](Ein Fehler, der nach dem Entdecken sofort ausgenutzt wird, um Schadsoftware in Systeme einzuschleusen ) gefixt wurde. Selbst Facebook-Mitarbeiter waren von der Java-Sicherheitslücke betroffen.[ 19 ](http://www.facebook.com/notes/facebook-security/protecting-people-on-facebook/10151249208250766)

 

Zum Seitenanfang

1.2.9Zeiger und Referenzen Zur vorigen ÜberschriftZur nächsten Überschrift

In Java gibt es keine Zeiger (engl. pointer), wie sie aus anderen Programmiersprachen bekannt und gefürchtet sind. Da eine objektorientierte Programmiersprache ohne Verweise aber nicht funktioniert, werden Referenzen eingeführt. Eine Referenz repräsentiert ein Objekt, und eine Variable speichert diese Referenz. Die Referenz hat einen Typ, der sich nicht ändern kann. Ein Auto bleibt ein Auto und kann nicht als Laminiersystem angesprochen werden. Eine Referenz unter Java ist nicht als Zeiger auf Speicherbereiche zu verstehen, obwohl sie intern durchaus so implementiert werden kann; das ist für den Benutzer aber nie sichtbar.

[zB]Beispiel *

Das folgende Programm zeigt, dass das Pfuschen in C++ leicht möglich ist und wir über eine Zeigerarithmetik Zugriff auf private Elemente bekommen können.[ 20 ](Auch ohne Compiler lässt sich das online prima testen: http://ideone.com. ) Für uns Java-Programmierer ist dies ein abschreckendes Beispiel.

#include <cstring>

#include <iostream>



using namespace std;



class VeryUnsafe {

public:

VeryUnsafe() { strcpy( password, "HaL9124f/aa" ); }

private:

char password[ 100 ];

};

int main() {

VeryUnsafe badguy;

char *pass = reinterpret_cast<char*>( & badguy );

cout << "Password: " << pass << endl;

}

Dieses Beispiel demonstriert, wie problematisch der Einsatz von Zeigern sein kann. Der zunächst als Referenz auf die Klasse VeryUnsafe gedachte Zeiger badguy mutiert durch die explizite Typumwandlung zu einem Char-Pointer pass. Problemlos können über diesen die Zeichen byteweise aus dem Speicher ausgelesen werden. Dies erlaubt auch einen indirekten Zugriff auf die privaten Daten.

In Java ist es nicht möglich, auf beliebige Teile des Speichers zuzugreifen. Auch sind private Variablen erst einmal sicher.[ 21 ](Ganz stimmt das allerdings nicht. Mit Reflection lässt sich da schon etwas machen, wenn die Sicherheitseinstellungen das nicht verhindern. ) Der Compiler bricht mit einer Fehlermeldung ab – bzw. das Laufzeitsystem löst eine Ausnahme (Exception) aus –, wenn das Programm einen Zugriff auf eine private Variable versucht.

 

Zum Seitenanfang

1.2.10Bring den Müll raus, Garbage-Collector! Zur vorigen ÜberschriftZur nächsten Überschrift

In Programmiersprachen wie C(++) lässt sich etwa die Hälfte der Fehler auf falsche Speicherallokation zurückführen. Mit Objekten und Strukturen zu arbeiten, bedeutet unweigerlich, sie anzulegen und zu löschen. Die Java-Laufzeitumgebung kümmert sich jedoch selbstständig um die Verwaltung dieser Objekte – die Konsequenz: Sie müssen nicht freigegeben werden, die automatische Speicherfreigabe von Java (engl. Garbage-Collector, kurz GC) entfernt sie. Nach dem expliziten Aufbauen eines Objekts überwacht das Laufzeitsystem von Java permanent, ob das Objekt noch gebraucht, also referenziert wird. Umgekehrt bedeutet das aber auch: Wenn auf einem Objekt vielleicht noch ein heimlicher Verweis liegt, kann der GC das Objekt nicht löschen. Diese so genannten hängenden Referenzen sind ein Ärgernis und zum Teil nur durch längere Debugging-Sitzungen zu finden.

Der GC ist ein nebenläufiger Thread im Hintergrund, der nicht referenzierte Objekte findet, markiert und dann von Zeit zu Zeit entfernt. Damit macht der Garbage-Collector die Funktionen free(…) aus C oder delete(…) aus C++ überflüssig. Wir können uns über diese Technik freuen, da damit viele Probleme verschwunden sind. Nicht freigegebene Speicherbereiche gibt es in jedem größeren Programm, und falsche Destruktoren sind vielfach dafür verantwortlich. An dieser Stelle sollte nicht verschwiegen werden, dass es auch ähnliche Techniken für C(++) gibt.[ 22 ](Ein bekannter Garbage-Collector stammt von Hans-J. Boehm, Alan J. Demers und Mark Weiser. Der Algorithmus arbeitet jedoch konservativ, das heißt, er findet nicht garantiert alle unerreichbaren Speicherbereiche, sondern nur einige. Eingesetzt wird der Boehm-Demers-Weiser-GC unter anderem in der X11-Bibliothek. Dort wurden die Funktionen malloc(...) und free(...) einfach durch neue Methoden ausgetauscht. )

Eine automatische Speicherbereinigung ist nicht ganz unproblematisch, da sie immer dann zuschlagen kann, wenn das System gerade etwas ganz Zeitkritisches machen möchte und Unterbrechungen nicht gelegen kommen. Doch die modernen Garbage-Collectors sind gut darin, wenig aktive Zyklen zu erkennen und die Arbeit gleichmäßig und auch auf mehrere Prozessorkerne zu verteilen. Doch automatische Speicherbereinigung ist nichts Neues, und die Verfahren sind lange erprobt. Schon frühere Programmiersprachen wie LISP (1958) und Smalltalk (1972) brachten einen Garbage-Collector mit, und alle modernen Programmiersprachen (bzw. deren Laufzeitumgebungen) besitzen eine automatische Speicherbereinigung.

 

Zum Seitenanfang

1.2.11Ausnahmebehandlung Zur vorigen ÜberschriftZur nächsten Überschrift

Java unterstützt ein modernes System, um mit Laufzeitfehlern umzugehen. In die Programmiersprache wurden Ausnahmen (engl. exceptions) eingeführt: Fehlerobjekte, die zur Laufzeit generiert werden und einen Fehler anzeigen. Diese Problemstellen können durch Programmkonstrukte gekapselt werden. Die Lösung ist in vielen Fällen sauberer als die mit Rückgabewerten und unleserlichen Ausdrücken im Programmfluss. In C++ gibt es ebenso Exceptions, die aber nicht so intensiv wie in Java benutzt werden.

Aus Geschwindigkeitsgründen überprüft C(++)[ 23 ](In C++ ließe sich eine Variante mit einem überladenen Operator lösen. ) die Array-Grenzen (engl. range checking) standardmäßig nicht, was ein Grund für viele Sicherheitsprobleme ist. Ein fehlerhafter Zugriff auf das Element n + 1 eines Arrays der Größe n kann zweierlei bewirken: Ein Zugriffsfehler tritt auf, oder – viel schlimmer – andere Daten werden beim Schreibzugriff überschrieben, und der Fehler ist nicht mehr nachvollziehbar.

Das Laufzeitsystem von Java überprüft automatisch die Grenzen eines Arrays. Diese Überwachungen können auch nicht abgeschaltet werden, wie es Compiler anderer Programmiersprachen mitunter erlauben. Eine clevere Laufzeitumgebung findet heraus, ob keine Überschreitung möglich ist, und optimiert diese Abfrage dann weg; Array-Überprüfungen kosten daher nicht mehr die Welt und machen sich nicht automatisch in einer schlechteren Performance bemerkbar.

 

Zum Seitenanfang

1.2.12Angebot an Bibliotheken und Werkzeugen Zur vorigen ÜberschriftZur nächsten Überschrift

Java ist mittlerweile schon so lange im Einsatz, dass es eine große Anzahl von Werkzeugen gibt, angefangen bei den Entwicklungsumgebungen mit unterstützenden Editoren über gute Debugger bis hin zu Werkzeugen zum Build-Management. Neben den Standardbibliotheken kommen weitere kommerzielle oder quelloffene Bibliotheken hinzu. Egal, ob es darum geht, PDF-Dokumente zu schreiben, Excel-Dokumente zu lesen, in SAP Daten zu übertragen oder bei einem Wincor-Bankautomaten den Geldauswurf zu steuern – für all das gibt es Java-Bibliotheken.

Neue Programmiersprachen haben es schwer, da mitzuhalten. Die Anzahl der Programmiersprachen ist in den letzten Jahren explodiert, doch so richtig können sie die breite Masse nicht anziehen, da eben Werkzeuge und Bibliotheken fehlen. Interessanter sind da schon die neuen Sprachen auf der Basis der JVM, denn das erlaubt weiterhin die Nutzung der Werkzeuge und Bibliotheken mit einer neuen Programmiersprache.

Werkzeuge und Bibliotheken sind es aber auch manchmal, die Teams vom Wechsel auf Java abhalten. Das trifft besonders die Spieleentwickler, die viel Erfahrung in C(++) haben und jahrelang Energie in Spiele-Frameworks gesteckt haben – dort sind die Tools einfach vorhanden, in Java (noch) nicht.

 

Zum Seitenanfang

1.2.13Einfache Syntax der Programmiersprache Java Zur vorigen ÜberschriftZur nächsten Überschrift

Die Syntax von Java ist bewusst einfach gehalten worden und strotzt nicht vor Operatoren oder Komplexität wie C++ oder Perl. Java erbte eine einfache und grundlegende Syntax wie die geschweiften Klammern von C, vermied es aber, die Syntax mit allen möglichen Dingen zu überladen. Da Programme häufiger gelesen als geschrieben werden, muss eine Syntax klar und durchgängig sein – je leichter Entwickler auf den ersten Blick sehen, was passiert, desto besser ist es.

»Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.« – John Woods

Es hat keinen Wert an sich, wenn Programme einfach nur kompakt sind, aber die Zeit, die ein Mensch zum Verstehen braucht, exponentiell steigt – je kompakter der Code, desto länger benötigt die menschliche Dekodierung. Auch wenn das folgende Perl-Beispiel aus »The Fifth Obfuscated Perl Contest Results«[ 24 ](https://de.wikipedia.org/wiki/Obfuscated_Perl_Contest) ganz bewusst als unleserliches Programm entworfen wurde, so wird jedem Betrachter schon beim Anblick schwummerig:

#:: ::-| ::-| .-. :||-:: 0-| .-| ::||-| .:|-. :||

open(Q,$0);while(<Q>){if(/^#(.*)$/){for(split('-',$1)){$q=0;for(split){s/\|

/:.:/xg;s/:/../g;$Q=$_?length:$_;$q+=$q?$Q:$Q*20;}print chr($q);}}}print"\n";

#.: ::||-| .||-| :|||-| ::||-| ||-:: :|||-| .:|

Eine einfachere Syntax lässt sich als Fluch (mehr Schreibarbeit) und auch als Segen (in der Regel leichter verständlich) auffassen. Java macht vieles richtig, aber es gibt ganz klar Stellen, an denen es auch hätte einfacher sein können (Stichwort Generics). Dennoch haben die Java-Entwickler gut daran getan, auf Konstrukte zu verzichten; zwei aus C(++) ausgelassene Fähigkeiten sollen exemplarisch vorgestellt werden.

In Java gibt es keine benutzerdefinierten überladenen Operatoren

Wenn wir einen Operator wie das Pluszeichen verwenden und damit Ausdrücke addieren, tun wir dies meistens mit bekannten Rechengrößen wie Fließkommazahlen (Gleitkommazahlen) oder Ganzzahlen. Da das gleiche Operatorzeichen auf unterschiedlichen Datentypen gültig ist, nennt sich so ein Operator überladen. Operatoren wie +, -, *, / sind für Ganzzahlen und Gleitkommazahlen ebenso überladen wie die Operatoren Oder, Und oder Xor für Ganzzahlen und boolesche Werte. Der Vergleichsoperator == bzw. != ist ebenfalls überladen, denn er lässt sich bei allen Zahlen, aber auch bei Wahrheitswerten oder Objektverweisen verwenden. Ein auffälliger überladener Operator ist das Pluszeichen bei Zeichenketten. Strings können damit leicht zusammengesetzt werden. Informatiker verwenden in diesem Zusammenhang auch gern das Wort Konkatenation (selten Katenation). Bei den Strings "Hallo" + " " + "du da" ist "Hallo du da" die Konkatenation der Zeichenketten.

Einige Programmiersprachen erlauben es, die vorhandenen Operatoren mit neuer Bedeutung zu versehen. In Java ist das nicht möglich. In C++ ist das Überladen von Operatoren erlaubt, sodass etwa das Pluszeichen dafür genutzt werden kann, geometrische Punktobjekte zu addieren, Brüche zu teilen oder eine Zeile in eine Datei zu schreiben. Repräsentieren die Objekte mathematische Konstrukte, ist es ganz praktisch, wenn Operationen über kurze Operatorzeichen benannt werden – ein matrix1.add(matrix2) ist mit längerem Methodennamen sperriger als ein matrix1 + matrix2. Obwohl benutzerdefinierte überladene Operatoren zuweilen ganz praktisch sind, verführte die Möglichkeit oft zu unsinnigem Gebrauch in C++. Daher haben die Sprachdesigner das für Java nicht vorgesehen, aber einige alternative Sprachen auf der JVM ermöglichen es, denn es ist eine Sprachbeschränkung und keine Beschränkung der virtuellen Maschine.

Neue Entwicklungen

Auch Java geht mit der Zeit und verändert sich. Das führt dazu, dass die Syntax erweitert wird und Entwickler Neues lernen müssen. Bisher gibt es keine überladenen Operatoren, aber vielleicht gibt es sie in zehn Jahren? Und da die Anforderung an statische Typsicherheit steigt, genauso wie der Wunsch, im Bereich funktionaler Programmierung aufzuholen, ist einiges passiert. Java war schon immer ein bisschen »geschwätzig«, doch die Symboldichte nahm ab Java 5 immer mehr zu und erreicht ihren (vorläufigen) Höhepunkt in Java 8.

Kein Präprozessor für Textersetzungen *

Viele C(++)-Programme enthalten Präprozessor-Direktiven wie #define, #include oder #if zum Einbinden von Prototyp-Definitionen oder zur bedingten Compilierung. Einen solchen Präprozessor gibt es in Java aus unterschiedlichen Gründen nicht:

  • Header-Dateien sind in Java nicht nötig, da der Compiler die benötigten Informationen wie Methodensignaturen direkt aus den Klassendateien liest.

  • Da in Java die Datentypen eine feste, immer gleiche Länge haben, entfällt die Notwendigkeit, abhängig von der Plattform unterschiedliche Längen zu definieren.

  • Pragma-Steuerungen sind im Programmcode unnötig, da die virtuelle Maschine ohne äußere Steuerung Programmoptimierungen vornimmt.

Ohne den Präprozessor sind schmutzige Tricks wie #define private public oder Makros, die Fehler durch eine doppelte Auswertung erzeugen, von vornherein ausgeschlossen. Im Übrigen findet sich der Private/Public-Hack im Quellcode von StarOffice. Die obere Definition ersetzt jedes Auftreten von private durch public – mit der Konsequenz, dass der Zugriffsschutz ausgehebelt ist.

Ohne Präprozessor ist auch die bedingte Compilierung mit #ifdef nicht mehr möglich. Innerhalb von Anweisungsblöcken können wir uns in Java damit behelfen, Bedingungen der Art if (true) oder if (false) zu formulieren; über den Schalter -D auf der Kommandozeile lassen sich Variablen einführen, die dann eine if-Anweisung über System.getProperty(…) zur Laufzeit prüfen kann.[ 25 ](Da besonders bei mobilen Endgeräten Präprozessor-Anweisungen für unterschiedliche Geräte praktisch sind, gibt es Hersteller-Erweiterungen wie die von NetBeans (http://tutego.de/go/nbpreprocessor). )

 

Zum Seitenanfang

1.2.14Java ist Open Source Zur vorigen ÜberschriftZur nächsten Überschrift

Schon seit Java 1.0 gibt es den Quellcode der Standardbibliotheken (falls er beim JDK mitinstalliert wurde, befindet er sich im Wurzelverzeichnis unter dem Namen src.zip), und jeder Interessierte konnte einen Blick auf die Implementierung werfen. Zwar legte Sun damals die Implementierungen offen, doch weder die Laufzeitumgebung noch der Compiler oder die Bibliotheken standen unter einer akzeptierten Open-Source-Lizenz. Zehn Jahre seit der ersten Freigabe von Java gab es Forderungen an Sun, die gesamte Java-Plattform unter eine bekanntere Lizenzform wie die GNU General Public License (GPL) oder die BSD-Lizenz zu stellen. Dabei deutete Jonathan Schwartz in San Francisco bei der JavaOne-Konferenz 2006 schon an: »It’s not a question of whether we’ll open source Java, now the question is how.« War die Frage also statt des »Ob« ein »Wie«, kündigte Rich Green bei der Eröffnungsrede der JavaOne-Konferenz im Mai 2007 die endgültige Freigabe von Java als OpenJDK[ 26 ](http://openjdk.java.net) unter der Open-Source-Lizenz GPL 2 an. Dem war Ende 2006 die Freigabe des Compilers und der virtuellen Maschine vorausgegangen.

Im Prinzip kann damit jeder Entwickler sein eigenes Java zusammenstellen und beliebige Erweiterungen veröffentlichen. Mit der Lizenzform GPL kann Java auf Linux-Distributionen Platz finden, die Java vorher aus Lizenzgründen nicht integrieren wollten.

OpenJDK und Oracle JDK

Auch wenn es sich so anhört, als ob das Oracle JDK und OpenJDK das Gleiche sei, ist das nicht ganz richtig. Zwar basiert das Oracle JDK auf dem OpenJDK (beim JDK 7 etwa zu 95 %), doch sind beim Oracle JDK immer noch proprietäre Dinge enthalten, und nicht alles ist hundertprozentig quelloffen und GPL. Das Oracle JDK steht unter der Binary Code License; genau die muss jeder abnicken, der das JDK von der Webseite laden möchte. Oracle JDK 8 ist die »offizielle« Version, die die Download-Seite von Oracle anbietet; die Quellen für das OpenJDK 8 liegen auf einem eigenen Server, http://download.java.net/openjdk/jdk8. Und http://openjdk.java.net/install/index.html erklärt, wie es unter den bekannten Unix-Paketmanagern installiert werden kann.

Das OpenJDK bildet die Referenzimplementierung für Java SE, nicht das Oracle JDK. Und trotz dieser minimalen Unterschiede zum Oracle JDK bildet das OpenJDK den zentralen Entwicklungsstrang für das JDK von Oracle. Der Fortschritt ist live zu beobachten, regelmäßig fixen und erweitern Hunderte von Entwicklern die Codebasis. Ein paar Statistiken zeigt http://www.ohloh.net/p/openjdk an:

  • >10 Millionen Zeilen Code insgesamt

  • >30.000 Commits in die Versionsverwaltung insgesamt seit dem Bestehen vom OpenJDK

  • 70 % vom OpenJDK ist Java-Code, 10 % C++.

  • Es stecken nach dem COCOMO-Model (Constructive Cost Model) über 1.800 Jahre Entwicklungsarbeit in dem Code.

 

Zum Seitenanfang

1.2.15Wofür sich Java weniger eignet Zur vorigen ÜberschriftZur nächsten Überschrift

Java wurde als Programmiersprache für allgemeine Probleme entworfen und deckt große Anwendungsgebiete ab (General-Purpose Language). Das heißt aber auch, dass es für ausreichend viele Anwendungsfälle deutlich bessere Programmiersprachen gibt, etwa im Bereich Skripting, wo die Eigenschaft, dass jedes Java-Programm mindestens eine Klasse und eine Methode benötigt, eher störend ist, oder im Bereich von automatisierter Textverarbeitung, wo andere Programmiersprachen eleganter mit regulären Ausdrücken arbeiten können.

Auch dann, wenn extrem maschinen- und plattformabhängige Anforderungen bestehen, wird es in Java umständlich. Java wurde plattformunabhängig entworfen, sodass alle Methoden auf allen Systemen lauffähig sein sollten. Sehr systemnahe Eigenschaften wie die Taktfrequenz sind nicht sichtbar, und sicherheitsproblematische Manipulationen wie der Zugriff auf bestimmte Speicherzellen (das PEEK und POKE) sind ebenso untersagt. Hier ist eine bei Weitem unvollständige Aufzählung von Dingen, die Java standardmäßig nicht kann:

Aus den genannten Nachteilen, dass Java nicht auf die Hardware zugreifen kann, folgt, dass die Sprache nicht so ohne Weiteres für die Systemprogrammierung eingesetzt werden kann. Treibersoftware, die Grafik-, Sound- oder Netzwerkkarten anspricht, lässt sich in Java nur über Umwege realisieren. Genau das Gleiche gilt für den Zugriff auf die allgemeinen Funktionen des Betriebssystems, die Windows, Linux oder ein anderes System bereitstellt. Typische System-Programmiersprachen sind C(++) oder Objective-C.

Aus diesen Beschränkungen ergibt sich, dass Java eine hardwarenahe Sprache wie C(++) nicht ersetzen kann. Doch das muss die Sprache auch nicht! Jede Sprache hat ihr bevorzugtes Terrain, und Java ist eine allgemeine Applikationsprogrammiersprache; C(++) darf immer noch für Hardwaretreiber und virtuelle Java-Maschinen herhalten. Die Standard-JVM ist in C++ geschrieben und wird vom GCC-Compiler bzw. Microsoft Visual Studio und XCode übersetzt.

Soll ein Java-Programm trotzdem systemnahe Eigenschaften nutzen – und das kann es mit entsprechenden Bibliotheken ohne Probleme –, bietet sich zum Beispiel der native Aufruf einer Systemfunktion an. Native Methoden sind Unterprogramme, die nicht in Java implementiert werden, sondern in einer anderen Programmiersprache, häufig in C(++). In manchen Fällen lässt sich auch ein externes Programm aufrufen und so etwa die Windows-Registry manipulieren oder Dateirechte setzen. Es läuft aber immer darauf hinaus, dass die Lösung für jede Plattform immer neu implementiert werden muss.

 

Zum Seitenanfang

1.2.16Java im Vergleich zu anderen Sprachen * Zur vorigen ÜberschriftZur nächsten Überschrift

Beschäftigen sich Entwickler mit dem Design von Programmiersprachen, werden häufig existierende Spracheigenschaften auf ihre Tauglichkeit hin überprüft und dann in das Konzept aufgenommen. Auch Java ist eine sich entwickelnde Sprache, die Merkmale anderer Sprachen aufweist.

Java und C(++)

Java basiert syntaktisch stark auf C(++), etwa bei den Datentypen, Operatoren oder Klammern, hat aber nicht alle Eigenschaften übernommen. In der geschichtlichen Kette wird Java gern als Nachfolger von C++ (und als Vorgänger von C#) angesehen, doch die Programmiersprache Java verzichtet bewusst auf problematische Konstrukte wie Zeiger.

Das Klassenkonzept – und damit der objektorientierte Ansatz – wurde nicht unwesentlich durch SIMULA und Smalltalk inspiriert. Die Schnittstellen (engl. interfaces), die eine elegante Möglichkeit der Klassenorganisation bieten, sind an Objective-C angelehnt – dort heißen sie Protocols. Während Smalltalk alle Objekte dynamisch verwaltet und in C++ der Compiler statisch Klassen zu einem Programm kombiniert, mischt Java in sehr eleganter Form dynamisches und statisches Binden. Alle Klassen – optional auch von einem anderen Rechner über das Netzwerk – lädt die JVM zur Laufzeit. Selbst Methodenaufrufe sind über das Netz möglich.[ 28 ](Diese Möglichkeit ist unter dem Namen RMI (Remote Method Invocation) bekannt. Bestimmte Objekte können über das Netz miteinander kommunizieren. ) In der Summe lässt sich sagen, dass Java bekannte und bewährte Konzepte übernimmt und die Sprache sicherlich keine Revolution darstellt; moderne Skriptsprachen sind da weiter und übernehmen auch Konzepte aus funktionalen Programmiersprachen.

Java und JavaScript

Obacht ist beim Gebrauch des Namens »Java« geboten. Nicht alles, bei dem Java im Wortstamm auftaucht, hat tatsächlich mit Java zu tun: JavaScript hat keinen großen Bezug zu Java – bis auf Ähnlichkeiten bei den imperativen Konzepten. Die Programmiersprache JavaScript wurde von Netscape entwickelt. Dazu ein Zitat aus dem Buch »The Java Developer’s Resource«:

»Java and JavaScript are about as closely related as the Trump Taj Mahal in Atlantic City is to the Taj Mahal in India. In other words Java and Java-Script both have the word Java in their names. JavaScript is a programming language from Netscape which is incorporated in their browsers. It is superficially similar to Java in the same way C is similar to Java but differs in all important respects.«[ 29 ](Kapitel 1, http://www.cafeaulait.org/books/jdr. Das Buch wurde bei Prentice-Hall verlegt (ISBN 0135707897). )

Die Klassennutzung ist mit einem Prototyp-Ansatz in JavaScript völlig anders als in Java, und JavaScript lässt sich zu den funktionalen Programmiersprachen zählen, was Java nun wahrlich nicht ist.

Java und C#/.NET

Da C# kurz nach Java und nach einem Streit zwischen Microsoft und Sun erschien und die Sprachen zu Beginn syntaktisch sehr ähnlich waren, könnte leicht angenommen werden, dass Java Pate für die Programmiersprache C# stand.[ 30 ](In Microsoft-Dokumenten findet sich über Java kein Wort. Dort wird immer nur davon gesprochen, dass C# andere Sprachen, wie etwa C++, VB und Delphi, als Vorbilder hatte. ) Doch das ist lange her. Mittlerweile hat C# eine so starke Eigendynamik entwickelt, dass Microsofts Programmiersprache viel innovativer ist als Java. C# ist im Laufe der Jahre komplex geworden, und Microsoft integriert ohne großen Abstimmungsprozess Elemente in die Programmiersprache, wo in der Java-Welt erst eine Unmenge von Personen diskutieren und abstimmen. Zeitweilig macht es den Eindruck, als könne Java nun auch endlich das, was C# bietet. So gesehen, profitiert Java heute von den Erfahrungen aus der C#-Welt. Bei den Lambda-Ergänzungen von Java 8 ist ausdrücklich die Übernahme der C#-Syntax hervorgehoben,[ 31 ](http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html) anders als bei der Microsoft-Dokumentation, die jegliche Ähnlichkeit zwischen C# und Java leugnet.

Während Oracle für Java eine Aufteilung in das Java SE für die »allgemeinen« Programme und das Java EE als Erweiterung für die »großen« Enterprise-Systeme vornimmt, fließt bei Microsoft alles in ein Framework, genannt .NET. Das ist natürlich größer als das Java-Framework, da sich mit .NET alles programmieren lässt, was Windows hergibt. Diese Eigenschaft fällt im Bereich GUI besonders auf, und das plattformunabhängige Java gibt dort weniger her.

Wäre nicht die Plattformunabhängigkeit, wäre es wohl ziemlich egal, ob große Systeme in Java oder einer .NET-Sprache entwickelt würden. Mono ist eine interessante Alternative zu Microsofts .NET-Entwicklungs- und Laufzeitumgebung, denn die quelloffene Nach-Implementierung läuft unter Linux, BSD, Mac OS, iOS, Android und anderen Systemen. Allerdings bringt die Patentunsicherheit Unternehmen vom großen Mono-Einsatz ab, und wichtige Teile aus dem .NET-Framework wie Windows Presentation Foundation (WPF), Windows Workflow Foundation (WWF) oder Entity Framework fehlen. Zudem übernahm im April 2011 die Firma Attachmate das Unternehmen Novell, das Mono bisher leitete, und setzte erst einmal viele Mono-Entwickler auf die Straße. Einige ehemals von Novell bezahlte Mono-Entwickler schlüpften daraufhin bei der im Mai 2011 gegründeten Firma Xamarin unter.

Etwas zynisch lässt sich bemerken, dass Java vielleicht nur deshalb noch lebt, weil Microsoft Windows attraktiv machen möchte, nicht aber andere Plattformen stärken möchte, indem es C# und das .NET Framework quelloffen unter eine Open-Source-Lizenz stellt und die Laufzeitumgebung auf unterschiedliche Plattformen bringt. Ein Hoch auf Industriepolitik! Microsoft brachte mit Silverlight eine Art abgespecktes .NET auf unterschiedlichen Systemen heraus, doch es hatte keine Auswirkungen auf die Client-Applikationen und zog keine Java-Entwickler an. Microsoft selbst ist auch nicht mehr sonderlich von Silverlight überzeugt und sieht für Smartphone- und Webanwendungen eine Kombination von HTML5, CSS3 und JavaScript vor.

 

Zum Seitenanfang

1.2.17Java und das Web, Applets und JavaFX Zur vorigen ÜberschriftZur nächsten Überschrift

Es ist nicht untertrieben, dem Web eine Schlüsselposition bei der Verbreitung von Java zuzuschreiben. Populär wurde Java in erster Linie durch die Applets – Java-Programme, die vom Browser dargestellt werden. Applets werden in einer HTML-Datei referenziert; der Browser holt sich eigenständig die Klassendateien und Ressourcen über das Netz und führt sie in der virtuellen Java-Maschine aus. Applets brachten erstmals Dynamik in die bis dahin statischen Webseiten – JavaScript kam erst später.

Obwohl Applets ganz normale grafische Java-Programme sind, gibt es verständlicherweise einige Einschränkungen. So dürfen Applets nicht – es sei denn, sie sind signiert – auf das Dateisystem zugreifen und beliebig irgendwelche Dateien löschen, was Java-Applikationen erst einmal problemlos können.

Netscape war die erste Firma, die einen Java-Interpreter in ihren Webbrowser fest integrierte. Das ist lange her. Heute gibt es keine vorinstallierte JVM mehr, sondern jeder populäre Browser bekommt Java-Unterstützung durch Oracles Hilfe. Es ist lange her, dass der Internet Explorer (IE) von Microsoft mit einer eigenen JVM bis Version 1.1.4 auftrumpfte. Heute verweist Microsoft zur Installation von Java (http://tutego.de/go/msinstalljava) ganz ungeniert auf die Oracle-Seite.

Dass nur noch Oracle als Hersteller einer JVM geblieben ist, hat zumindest den Vorteil, das so auf allen populären Browsern immer die aktuellste und sicherste Java-Version zu finden ist, hat aber natürlich auch die Schwäche, dass, wenn eine Sicherheitslücke bekannt wird, dann gleich Millionen von Rechnern gefährdet sind.

Java auf der Serverseite statt auf der Client-Seite und im Browser

Obwohl das Web Java bekannt gemacht hat und dort viele Einsatzgebiete liegen, ist Java nicht auf dieses Medium beschränkt. Nahezu alle großen IT-Unternehmen haben ihre Zuneigung zu dieser Sprache entdeckt. Es hat sich gezeigt, dass die Devise »write once, run anywhere« (WORA) auf der Serverseite weitgehend zutrifft. Java ist inzwischen wohl die wichtigste Sprache für die Gestaltung von Internet-Applikationen auf dem Server. Sie unterstützt strukturiertes und objektorientiertes Programmieren und ist ideal für größere Projekte.

Nach dem anfänglichen Hype heißt es heute paradoxerweise oft, dass Java zu langsam für Client-Anwendungen sei. Bei der Startzeit stimmt das, weniger bei der Ausführungsgeschwindigkeit. Virtuelle Maschinen sind aufgrund der Entwicklung von JIT-Compilern und der HotSpot-Technologie in den letzten Jahren sehr viel schneller geworden. Auch die Geschwindigkeit der Prozessoren ist ständig weiter gewachsen, wie auch die Anzahl der CPU-Kerne. Dennoch kommt Java auf der Client-Seite nicht so richtig in Fahrt, was aber weniger an den Möglichkeiten von Java liegt, sondern eher am Abflauen von Desktop-Applikationen insgesamt und am Zuwachs von Web-Applikationen. Und damit ist Java doch wieder auf der Serverseite angekommen.

RIA mit JavaFX

Rich Internet Applications (RIA) sind grafisch anspruchsvolle Webanwendungen, die in der Regel Daten aus dem Internet beziehen. Viele Jahre beherrschte Adobe Flash hier fast zu 100 % das Feld, und Microsoft spielte mit Silverlight zeitweilig mit, und auch Oracle wollte aus strategischen Gründen das Feld nicht den Mitbewerbern überlassen. Als sich abzeichnete, dass Applets unbeliebt sind, veröffentlichte Oracle nach längerer interner Projektphase Ende 2008 die JavaFX-Plattform. JavaFX ist ein ganz neuer GUI-Stack und komplett von Swing und AWT entkoppelt.

In der ersten Version gehörte die Programmiersprache JavaFX Script mit dazu, doch ab Version JavaFX 2 hat Oracle die Richtung geändert: JavaFX ist nun eine pure Java-Bibliothek, und die eigenwillige Programmiersprache JavaFX Script ist Vergangenheit. Mit Skriptsprachen auf der Java-VM ist jedoch ein vergleichbares »Feeling« gewährleistet.

Flash, Silverlight und JavaFX haben alle ein Problem: Sie benötigen ein Browser-Plugin. Das macht sie unattraktiv für Unternehmen, da im Internet kein Kunde ausgeschlossen werden soll. Früher, als die Webstandards noch nicht so weit entwickelt waren, brachten Flash, Silverlight und JavaFX Dynamik auf die Webseite, doch heute sind aufwändige Webanwendungen mit JavaScript und HTML 5/CSS3 realisierbar. Auch Microsoft stoppte bei Silverlight 5 die Entwicklung und bevorzugt nun Lösungen auf der Basis von JavaScript + HTML 5 + CSS3, insbesondere für mobile Endgeräte, da den Redmondern klar ist, dass es nie Silverlight auf dem iPhone oder Android geben wird.[ 32 ](Mit https://xamarin.com/platform gibt es interessante Ansätze. ) Adobe selbst beginnt mit Konvertern von Flash nach HTML 5/CSS3/JavaScript und zeigt damit auch die Zukunft auf. JavaFX wird daher nie einen ernsthaften Anteil im Web gewinnen, wohl aber auf einem anderen Gebiet, das weder JavaScript, Flash noch Silverlight abdecken: Blu-ray-Player und Set-Top-Boxen. Die Blu-ray Disc Association (BDA) hat mit Blu-ray Disc Java (kurz BD-J) eine Spezifikation verabschiedet, die beschreibt, wie Blu-ray-Player Menüs oder andere interaktive Anwendungen ausführen können (das Ganze basiert auf einer abgespeckten Java-Version, der Java ME). Im Moment wird diskutiert, ob zukünftig die Anforderungen an die Blu-ray-Player so hochgeschraubt werden, dass sie interaktive JavaFX-Anwendungen ausführen können. Das wäre sicherlich ein Bereich, in dem JavaFX punkten könnte, aber wohl kaum im Internet, und auch für mobile Endgeräte hat das ehemals geplante JavaFX Mobile zusammen mit JavaFX Script ausgedient.

Auch wenn JavaFX im Web keine große Rolle spielt und wir JavaFX-Anwendungen nur über Umwege auf mobilen Endgeräten sehen, ist doch die Richtung vorgezeichnet, dass JavaFX Swing und AWT beerbt. Grundsätzlich nimmt jedoch die Bedeutung von Desktop-Technologien ab, und nach anfänglichem Hype um JavaFX hat Oracle viele Entwickler abgezogen, sodass AWT/Swing und JavaFX bis auf ein paar Bugfixes wenig Liebe empfängt.

 

Zum Seitenanfang

1.2.18Features, Enhancements (Erweiterungen) und ein JSR Zur vorigen ÜberschriftZur nächsten Überschrift

Java wächst von Version zu Version, sodass es regelmäßig größere Zuwächse bei den Bibliotheken gibt sowie wohlproportionierte Änderungen an der Sprache und minimale Änderungen an der JVM. Änderungen an der Java SE-Plattform werden in Features und Enhancements kategorisiert. Ein Enhancement ist dabei eine kleine Änderung, die nicht der Rede wert ist – dass etwa eine kleine Funktion wie isEmpty() bei der Klasse String hinzukommt. Diese Erweiterungen bedürfen keiner großen Abstimmung und Planung und werden von Oracle-Mitarbeitern einfach integriert.

Features dagegen sind in Bezug auf den Aufwand der Implementierung schon etwas Größeres. Oder aber die Community erwartet diese Funktionalität dringend – das macht sie deutlich, indem sie einen Feature-Request auf Oracles Website platziert und viele für dieses Feature stimmen. Eine weitere Besonderheit ist, wie viele dieser Features geplant werden. Denn oftmals entsteht ein JSR (Java Specification Request), der eine bestimmte Reihenfolge bei der Planung vorschreibt. Die meisten Änderungen an den Bibliotheken beschreibt ein JSR, und es gibt mittlerweile Hunderte von JSRs.

In der Anfangszeit war die Implementierung gleichzeitig die Spezifikation, aber mittlerweile gibt es für einen Java-Compiler, die JVM und diverse Bibliotheken eine beschreibende Spezifikation. Das gilt auch für Java als Gesamtes. Java SE ist eine Spezifikation, die zum Beispiel das Oracle JDK, OpenJDK, Apache Harmony[ 33 ](http://harmony.apache.org. Seit Ende 2011 »retired«, also »in Pension« und somit tot. ) oder GNU Classpath[ 34 ](http://www.gnu.org/s/classpath. Seit Anfang 2009 keine neue Version mehr. Da das OpenJDK wie auch GNU Classpath unter der GPL-Lizenz steht, gibt es keine Notwendigkeit mehr für eine weitere Java SE-Implementierung unter der GPL. ) realisiert. Während das Oracle JDK (kurz JDK) auf dem OpenJDK basiert und das OpenJDK unter der GPL-Lizenz steht, ist Apache Harmony ein Projekt unter der Apache-Lizenz. Das OpenJDK für Windows und Linux ist die Referenzimplementierung und definiert somit den Standard. (Das ist dann wichtig, wenn eben gewisse Eigenschaften doch nicht dokumentiert sind.) Die Java SE 8 Platform wird im JSR 337 beschrieben,[ 35 ](http://www.jcp.org/en/jsr/detail?id=337) der ein so genanntes Umbrella-JSR ist, weil er andere JSRs referenziert.

 

Zum Seitenanfang

1.2.19Die Entwicklung von Java und seine Zukunftsaussichten Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Buch über Java sollte im Allgemeinen eine positive Grundstimmung haben und die Leser nicht mit apokalyptischen Szenarien verschrecken. Doch gibt es einige Indizien dafür, dass sich Java als Programmiersprache nur langsam und nicht großartig weiterentwickeln wird und eher in einen »Wartungsmodus« übergeht. Zu dem Erfolg der Sprache zählt, dass sie im Vergleich zum Vorgänger C++ deutlich einfacher zu erlernen war und von »gefährlichen« syntaktischen Konstrukten die Finger ließ (obwohl immer noch einige Punkte übrig blieben). So schrieb einer der Sprachväter, James Gosling – der nach der Übernahme von Sun durch Oracle das Unternehmen verließ –, schon 1997:

»Java ist eine Arbeitssprache. Sie ist nicht das Produkt einer Doktorarbeit, sondern eine Sprache für einen Job. Java fühlt sich für viele Programmierer sehr vertraut an, denn ich tendiere stark dazu, Dinge zu bevorzugen, die schon oft verwendet wurden, statt Dingen, die eher wie eine gute Idee klangen.«[ 36 ](Im Original: »Java is a blue collar language. It’s not PhD thesis material but a language for a job. Java feels very familiar to many different programmers because I had a very strong tendency to prefer things that had been used a lot over things that just sounded like a good idea.« (http://www.computer.org/portal/web/csdl/doi/10.1109/2.587548) )

Diese Haltung besteht bis heute. Java soll bloß einfach bleiben, auch wenn die anderen Programmiersprachen um Java herum syntaktische Features haben, die jeden Compilerbauer ins Schwitzen bringen. Bedeutende Sprachänderungen gab es eigentlich nur in Java 5 (also etwa zehn Jahre nach der Einführung) und in Java 8.

Bei der Dreifaltigkeit der Java-Plattform – 1. Java als Programmiersprache, 2. den Standardbibliotheken und 3. der JVM als Laufzeitumgebung – lässt sich erkennen, dass es große Bewegung bei den unterschiedlichen Programmiersprachen auf der Java-Laufzeitumgebung gibt. Es zeichnet sich ab, dass Java-Entwickler weiterhin in Java entwickeln werden, aber eine zweite Programmiersprache auf der JVM zusätzlich nutzen. Das kann JavaScript, Groovy, Scala, Jython, JRuby oder eine andere JVM-Sprache sein. Dadurch, dass die alternativen Programmiersprachen auf der JVM aufsetzen, können sie alle Java-Bibliotheken nutzen und daher Java als Programmiersprache in einigen Bereichen ablösen. Dass die alternativen Sprachen auf die üblichen Standardbibliotheken zurückgreifen, funktioniert reibungslos, allerdings ist der umgekehrte Weg, dass etwa Scala-Bibliotheken aus Jython heraus genutzt werden, (noch) nicht standardisiert. Bei der .NET-Plattform klappt das besser, und hier ist es wirklich egal, ob C# oder VB.NET Klassen deklariert oder nutzt.

Als die Übernahme von Sun vor der Tür stand, zeigte Oracle sich sehr engagiert gegenüber den Sun-Technologien. Nach der Übernahme wandelt sich das Bild nun etwas, und Oracle hat eher für negative Schlagzeilen gesorgt, etwa als es die Unterstützung für OpenSolaris eingestellt hat, seitdem es MySQL zurückfährt und als Gefahr für die eigene Datenbank sieht und weil es OpenOffice erst spät an Apache übergeben hat (als sich LibreOffice schon verselbstständigt hatte). Auch was die Informationspolitik und Unterstützung von Usergroups angeht, verhält sich Oracle ganz anders als Sun. Verlässliche Zeitaussagen zu Java 7 gab es lange Zeit nicht, und durch die Klage gegen Google wegen Urheberrechtsverletzungen in Android machte sich Oracle auch keine Freunde. Android gilt als Beweis, dass Java auf dem Client tatsächlich erfolgreich ist. Anlässlich der Sicherheitslücken in Java machte das Unternehmen ebenfalls keine gute Figur, insgesamt dürfte auf einer Bewertung zu finden sein: »Oracle hat sich bemüht, den Anforderungen gerecht zu werden.«

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel

Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?

Ihre Meinung



 Buchempfehlungen
Zum Katalog: Java ist auch eine Insel

Java ist auch eine Insel




Zum Katalog: Java SE 9-Standard-Bibliothek

Java SE 9-Standard-Bibliothek




Zum Katalog: Professionell entwickeln mit Java EE 8

Professionell entwickeln mit Java EE 8




Zum Katalog: Entwurfsmuster

Entwurfsmuster




Zum Katalog: IT-Projektmanagement

IT-Projektmanagement




 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2017

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de