Seitentitel: Java

Java

 

Solange kein plattformabhängiger Code verwendet wird, läuft Bytecode ohne weitere Anpassungen auf verschiedenen Computern und Betriebssystemen. Sun bietet neben dem eigenen UNIX-Derivat Solaris auch Java-VMs für Linux und Windows an. Andere Hersteller, wie z. B. Apple, lassen Ihre Java-VM für ihre Plattform (Mac OS X) zertifizieren, damit Plattformunabhängkeit auch in der Praxis funktionieren kann.

 

Von Portierung spricht man bei Java in der Regel, wenn Source- oder Bytecode auf eine höhere Java-Version gebracht werden soll. Meistens sind Java-Programme deshalb nur für bestimmte Java-Versionen getestet oder zertifiziert.

 

Der ursprüngliche Entwurf der Programmiersprache Java strebte im wesentlichen fünf Ziele an.

 

  • Sie soll eine objektorientierte Programmiersprache sein
  • Sie soll es ermöglichen, das gleiche Programm auf unterschiedlichen Computersystemen auszuführen
  • Sie soll eingebaute Unterstützung für die Verwendung von Computernetzen enthalten
  • Sie soll Code aus entfernten Quellen sicher ausführen können. Dieser Punkt wird über das Sicherheitskonzept von Java erreicht, das aus drei Schichten besteht: 1. dem Code-Verifier (deutsch „Code-Überprüfer“), der sicherstellt, dass die VM keinen ungültigen Bytecode ausführen kann. 2. den Class-Loadern (deutsch „Klassenlader“), die die sichere Zuführung von Klasseninformationen zur JVM steuern (diese ist dabei kein Interpreter, siehe unten). 3. den Security-Managern (deutsch „Sicherheitsverwalter“), die sicher stellen, dass nur Zugriff auf Programmobjekte erlaubt wird, für die entsprechende Rechte vorhanden sind
  • Die erfolgreichen Aspekte bereits verbreiteter objektorientierter Programmiersprachen wie C++ sollen auch für Java-Programmierer zur Verfügung stehen

Objektorientierung

 

Die Sprache Java gehört zu den objektorientierten Programmiersprachen. Die Grundidee der objektorientierten Programmierung ist die softwaretechnische Abbildung in einer Art und Weise, wie wir Menschen auch Dinge der realen Welt erfahren. Die Absicht dahinter ist, große Softwareprojekte einfacher verwalten zu können, und sowohl die Qualität von Software zu erhöhen als auch Fehler zu minimieren. Ein weiteres Ziel der Objektorientierung ist ein hoher Grad der Wiederverwendbarkeit von Softwaremodulen.

 

Ein neuer Aspekt von Java gegenüber den zuvor verbreitetsten objektorientierten Programmiersprachen C++ und Smalltalk ist die explizite Unterscheidung zwischen Schnittstellen und Klassen, die auch durch entsprechende Schlüsselwörter interface und class zur Geltung kommt.

 

Java ist nicht vollständig objektorientiert: Die Grunddatentypen (int, boolean usw.) und Literale sind keine Objekte (siehe auch unter Java-Syntax).

 

Reflection

 

Java bietet eine Reflection-API als Bestandteil der Laufzeitumgebung. Damit ist es möglich, zur Laufzeit auf Klassen und Methoden zuzugreifen, deren Existenz oder genaue Ausprägung zur Zeit der Programmerstellung nicht bekannt war.

 

Annotationen

 

Seit Java 5.0 gibt es eine Syntax-Erweiterung namens Annotationen. Sinn der Annotationen ist die automatische Erzeugung von Code und anderen in der Software-Entwicklung wichtigen Dateien für wiederkehrende Muster anhand möglichst kurzer Hinweise im Quelltext. Bislang wurden in Java dafür ausschließlich Javadoc-Kommentare mit speziellen JavaDoc-Tags verwendet, die von Doclets wie z. B. dem XDoclet ausgewertet wurden.

 

Diese Annotationen können auch in den kompilierten Class-Files enthalten sein, der Quelltext wird also für ihre Verwendung nicht benötigt. Insbesondere sind die Annotationen auch über die Reflection-API zugänglich. So können sie zum Beispiel zur Erweiterung des Bean-Konzeptes verwendet werden.

 

Write Once, Run Anywhere

 

Java funktioniert nach dem Konzept Write Once, Run Anywhere (deutsch: Schreibe einmal, laufe überall). Das bedeutet, dass man ein Programm, das in Java programmiert wurde, nur einmal zu kompilieren braucht und es auf allen anderen Systemen läuft, die eine Java-Laufzeitumgebung (Java Runtime Environment bzw. JRE) besitzen. Dies wird dadurch erreicht, dass Java zunächst in Bytecode kompiliert wird, dieser wird von der JRE beim Starten des Programmes erst in die Maschinensprache kompiliert (Man spricht hier von einem JIT-Compiler).

 

Der Bytecode funktioniert also als Zwischencode, zwischen Programmiersprache und Maschinensprache. So ist das Javaprogramm nicht an eine bestimmte Maschine gebunden. Die Java Runtime Environment existiert für weit verbreitete Betriebssysteme wie Microsoft Windows, Linux, Solaris, Mac OS X, AIX und viele andere. Daneben gibt es eine JRE nicht nur für Server- und Desktopbetriebssysteme, sondern auch für viele Embedded Systeme wie Mobiltelefone, PDAs, sowie Smartcards und andere technische Plattformen, wie Auto und TV. Die Plattformunabhängigkeit endet jedoch für solche Systeme, für die keine Java Virtual Machine existiert, zumeist ältere oder sehr exotische Systeme.

 

Es gibt aber auch Compiler, die Java direkt in Maschinencode übersetzen (Siehe Java: Native Compiler).

 

Wer von „Plattformunabhängigkeit“ und „Java“ spricht, muss zwischen der Java-VM selbst und den Programmen, die in Java geschrieben sind unterscheiden. Die Java-VM, die die eigentliche Plattformunabhängigkeit ermöglicht, ist selbst plattformabhängig, da sie auf ein bestimmtes Betriebssystem und eine Rechnerarchitektur angepasst ist. Z. B. ist Suns Java-VM für Windows in C++ geschrieben und durch C++ kompiliert. Andere Komponenten des JDKs wie z. B. der Java-Compiler, sind in purem Java geschrieben und damit wieder plattformunabhängig, d. h. der Bytecode des Compilers ist auf unterschiedlichen Plattformen identisch. Das Gleiche gilt für den Bytecode von Programmen, die in Java geschrieben und durch einen Java-Compiler kompiliert wurden.

 

Modulare Ausführung auf fernen Computern

 

Java bietet die Möglichkeit, Klassen zu schreiben, die in unbekannten Containern ablaufen. Beispielsweise lassen sich Applets in Webbrowsern, die Java unterstützen, ausführen. Das Sicherheitskonzept von Java kann dazu eingesetzt werden, dass unbekannte Klassen dabei keinen Schaden anrichten können, was vor allem bei Applets wichtig ist (siehe auch Sandbox). Beispiele für Java Container-Module sind Applets, Servlets, Portlets, Midlets, Translets, Doclets und Enterprise JavaBeans.

 

 

Merkmale der Sprache

 

Zu Java gehört eine umfangreiche Klassenbibliothek. Dem Programmierer wird damit eine einheitliche, vom zugrunde liegenden Betriebssystem unabhängige Schnittstelle (Application programming interface, API) angeboten.

 

Mit Java 1.1 wurden die Java Foundation Classes (JFC) eingeführt, die u. a. Swing bereitstellen, das zur Erzeugung plattformunabhängiger grafischer Benutzerschnittstellen (GUI) dient und auf AWT basiert.

 

Compiler

 

Mit einem Java-Compiler ist es möglich, Java-Sourcecode (Dateiendung .java) in einen ausführbaren Code zu kompilieren. Grundsätzlich unterscheidet man zwischen Bytecode- und Nativecode-Compilern. Des weiteren verwenden einige Java-Laufzeitumgebungen einen JIT-Compiler um Bytecode häufig genutzter Programmteile in nativen Maschinencode zu übersetzen während das Programm läuft.

 

Bytecode-Compiler

 

Java-Programme werden im Normalfall in einen nicht direkt ausführbaren Bytecode (Dateiendung .class) übersetzt, den Maschinencode der Java-Plattform, der in der Java Runtime Environment (JRE) ausgeführt wird. Es ist dabei festzuhalten, dass diese Ausführung von Bytecode nichts mit einem Interpreter zu tun hat, wie er z. B. in Basic zum Einsatz kommt.

 

Die aktuelle HotSpot-Technologie kompiliert den Bytecode zur Laufzeit vielmehr in nativen Prozessorcode und optimiert diesen abhängig von der verwendeten Plattform. Diese Optimierung findet dabei sukzessive statt, so dass der Effekt auftritt, dass Programmteile erst nach mehrmaliger Abarbeitung schneller werden. Auf der anderen Seite führt diese Technologie, die ein Nachfolger der Just-In-Time-Compilierung ist, dazu, dass Java-Bytecodes mindestens genau so schnell wie native, kompilierte Programme ausgeführt werden.

 

Die HotSpot-Technologie ist seit der JRE Version 1.3.0 verfügbar und wurde seitdem immer weiter verbessert.

 

  • javac (Teil des JDK) von Sun Microsystems
  • Jikes von IBM

Native Compiler

 

Es existieren auch Compiler für Java, die Java-Quelltexte oder Java-Bytecode in normalen Maschinencode übersetzen können, sogenannte Ahead-Of-Time-Compiler. Nativ kompilierte Programme haben den Vorteil, keine JavaVM mehr zu benötigen, aber auch den Nachteil, nicht mehr plattformunabhängig zu sein. Hier trifft die Bezeichnung „write once, run anywhere“ nicht mehr zu.

 

  • GNU Compiler for Java (GCJ)
  • MinGW
  • Cygwin
  • Excelsior JET

Wrapper

 

Ein Wrapper (in diesem Zusammenhang) ist ein ausführbares Programm, welches als Ersatz für ein Java Archive (Dateiendung .jar) dient. Er sucht selbständig nach einer installierten Java-Laufzeitumgebung, um das Programm zu starten und informiert den Benutzer darüber, wo er eine Laufzeitumgebung herunterladen kann, sofern noch keine installiert ist. Es ist also immer noch eine Laufzeitumgebung nötig, um das Programm starten zu können.

 

Java Web Start ist ein etwas eleganterer Ansatz für diese Problematik – er ermöglicht die einfache Aktivierung von Anwendungen mit einem einzigen Mausklick und garantiert, dass Sie immer die neueste Version der Anwendung ausführen. Dadurch werden komplizierte Installations- oder Aktualisierungsprozeduren vermieden.

 

  • JSmooth (Lizenz: GPL)
  • Launch4J (Lizenz: GPL)
  • JBuilder von Borland und NSIS (Java Launcher) sind ebenfalls in der Lage einen Wrapper für Windows zu erstellen