Zum Inhalt springen

Java (Programmiersprache)

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 31. Juli 2003 um 20:36 Uhr durch 213.196.196.21 (Diskussion). Sie kann sich erheblich von der aktuellen Version unterscheiden.


Java ist eine Programmiersprache. Sie wurde ab 1991 von James Gosling und anderen Ingenieuren des amerikanischen Computerherstellers Sun Microsystems entwickelt. Ziel war eine schlanke Sprache für Kleingeräte mit geringer Hardwarekapazität. Offiziell wurde Java erstmals am 23. Mai 1995 vorgestellt. Der Begriff leitet sich von einer Bezeichnung für eine starke Sorte Kaffee ab.

Grundkonzepte der Sprache

Der Entwurf der Sprache verfolgte vier Hauptziele:

  1. Objektorientierung
  2. Plattformunabhängigkeit (d.h. Unabhängigkeit vom Betriebssystem und von Hardware)
  3. Vernetzbarkeit
  4. Sichere Ausführung auf entfernten Computern

Objektorientierung

Die Sprache Java ist objektorientiert aufgebaut. 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 managen 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 Wiederverwendung von Softwaremodulen.

Plattformunabhängigkeit

Java ist plattformunabhängig, d. h. Java-Programme laufen unabhängig vom Betriebssystem und der eingesetzten Hardware. Java-Programme laufen nicht nur auf einem PC, einer Workstation oder einem Server, sondern auch auf Organizern und Handies. Dies wird dadurch erreicht, dass es sich bei einem kompilierten Java-Programm nicht um direkt ausführbaren Maschinencode handelt, sondern um maschinenunabhängigen Bytecode.

Zum Ausführen von Java-Programmen wird ein Stück Software, die so genannte Java VM benötigt. Es gibt mittlerweile aber auch Hardware-Lösungen, also Prozessoren, deren Maschinensprache selbst der Java-Bytecode ist.


Sichere Ausführung auf entfernten Computern

Eine Besonderheit von Java sind Java-Applets. Das sind meist kleine Java-Programme, die einen Java fähigen Web-Browser benötigen, um abzulaufen. Dies wird häufig durch Plug-ins gelöst. Das Applet ist dabei in der HTML-Seite eingebettet. Die Rechte eines Applets werden standardmäßig stark eingeschränkt, d. h. es erhält keinen Zugriff auf lokale Ressourcen (Applets dürfen nur in der so genannten Sandbox "spielen"). Seit Java 2 gibt es die Möglichkeit, Applets zu signieren. Mit Hilfe dieser Signatur ist es möglich, den Autor eines Applets eindeutig zu identifizieren. Unter Berücksichtigung dieser Information kann der Benutzer dann dem Applet selektiv (wenn notwendig) mehr Rechte zugestehen.

Im Unterschied zu Java-Applets, lassen sich mit Java Web Start vollwertige Java Anwendungen über das Netz ausführen. Diese Technologie ermöglicht eine automatische Installation von Anwendungen auf dem lokalen System. Dies wird erreicht, indem eine spezielle XML Datei im Internet bereitgestellt wird. In dieser werden die einzelnen Komponenten der Anwendung beschrieben. Diese werden dann auf den Rechner des Anwenders heruntergeladen. Bei jedem Start wird erneut überprüft, ob neuere Komponenten vorliegen. So arbeitet der Anwender stets mit der aktuellsten vom Autor des Programms zur Verfügung gestellten Version. Wie bei Applets können Komponenten signiert sein. Der Anwender hat dabei ebenfalls die volle Kontrolle über die Vergabe der Rechte.

Features der Sprache

Um große Projekte strukturieren zu können und saubere Schnittstellen zu Bibliotheken zu schaffen, können die Klassen zu Paketen (Packages) zusammengefasst werden. Die Zugriffe auf Klassen und Methoden eines fremden Packages können - ähnlich wie innerhalb einer Klasse durch private und public - geregelt werden.

Weiter unterstützt die Sprache Threads (gleichzeitig ablaufende Programmteile) und Exceptions (wörtlich: Ausnahmesituationen, das sind Objekte, die bei der Unterbrechung des Programm-Ablaufes an die nächst höhere aufrufende Methode weitergereicht werden.)

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.

Syntax

Ein Beispielprogramm, das eine Meldung auf der Konsole ausdruckt:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}


Kontrollfluss-Strukturen

Schleifen


while (Boole'scher Ausdruck) {
    Anweisung(en)
}


do {
   Anweisung(en)
} while (Boole'scher Ausdruck);


for (Initiallisierung ; Endbedingung ; Inkrement) {
   Anweisung(en)
}


Wenn-Dann-Anweisungen

if (Boole'scher Ausdruck) {
   Anweisung(en)
}


if (Boole'scher Ausdruck) {
      Anweisung(en)
} else {
      Anweisung(en)
}

Mit else if können beliebig komplexe Wenn-Dann-Anweisungen konstruiert werden

if (Boole'scher Ausdruck) {
    Anweisung(en)
} else if (Boole'scher Ausdruck) {
    Anweisung(en)
} else if (Boole'scher Ausdruck) {
    Anweisung(en)
} else {
    Anweisung(en)
}


switch (Integerausdruck) {
   case konstanter Integerausdruck:
        Anweisung(en)
        break;
   ...
   default:
        Anweisung(en)
        break;
}


Ausnahmebehandlung

try {
    Anweisung(en)
} catch (Bezeichnung des Ausnahmetyps) {
    Anweisung(en)
} catch (Bezeichnung des Ausnahmetyps) {
    Anweisung(en)
} finally {
    Anweisung(en)
}


Sprunganweisungen

Man kann vor Schleifen ein Label setzten

meinLabel: eineSchleife (for/while/do);

Die Anweisung

break;

ohne Label beendet die innerste Schleife


Das Label kann dann benutzt werden um z.B. aus einer inneren FOR-, einer WHILE oder einer DO-Schleife direkt in eine äußere auszubrechen.

break meinLabel;

Eine continue-Anweisung beendet den aktuellen Iterationsschritt fährt mit der nächsten Schleifeniteration weiter.

continue;

Analog kann mit

continue label;

direkt in einer äußeren Schleife weitergefahren werden.


Die Anweisung

return;

beendet eine Methode.

Mit

return einWert;

kann der aufrufenden Methode ein Wert übermittelt werden

Grunddatentypen

Grunddatentypen, die auch als 'primitive' Datentypen bezeichnet werden, sind in Java ebenfalls plattformunabhängig (sie werden stets im Big Endian-Format gespeichert, wenn sie größer als 8 Bit sind):

  • boolean (Werte sind true und false)
  • char (16-bit Unicode-Wert, ohne Vorzeichen)
  • byte (8 bit, Zweierkomplement-Darstellung, mit Vorzeichen)
  • short (16-Bit Ganzzahl, Zweierkomplement-Darstellung, mit Vorzeichen)
  • int (32-Bit Ganzzahl, Zweierkomplement-Darstellung, mit Vorzeichen)
  • long (64-Bit Ganzzahl, Zweierkomplement-Darstellung, mit Vorzeichen)
  • float (Gleitkommazahl 32 Bit, IEEE 754)
  • double (Gleitkommazahl 64 Bit, IEEE 754)

Beispiele für literale Werte:

  • 'c' char
  • true boolean
  • false boolean
  • 123 int
  • 5230L long
  • 12.730 double
  • 12.730D double
  • 12.730F float
  • 12.730e3 double

Für die primitiven Typen existieren in Java entsprechende Wrapperklassen zum Instanzieren von Objekten.

Liste der reservierten Worte

abstract assert boolean break byte case catch char class const continue default do double else extends false final finally float for goto if implements import instanceof int interface long native new null package private protected public return short static strictfp super switch synchronized this throw throws transient true try void volatile while

Funktion der reservierten Worte

const und goto sind zwar reserviert, aber ohne Funktion, also keine Schlüsselwörter im eigentlichen Sinn. Sie dienen lediglich dem Copmiler zur Ausgabe sinnvoller Fehlermeldungen für Umsteiger von C / C++.

true, false und null sind Literale, jedoch ebenfalls eigentlich keine Schlüsselwörter im engeren Sinn.

Mit assert werden Assertions realisiert.

private, protected und public sind Zugreifbarkeitsmodifizierer:

Die Klasse selbst,
Innere Klassen
Klassen im selben PackageSubklassenSonstige Klassen
privateJaNeinNeinNein
- ("package default")JaJaNeinNein
protectedJaJaJaNein
publicJaJaJaJa

abstract, final, static sind Polymorphie-Modifizierer. static kann vor allen Membern außer Konstruktoren stehen und bedeutet, dass der betreffende Member im Kontext der Klasse verwendbar ist und kein Objekt benötigt. abstract kann vor Klassen und Methoden stehen und bedeutet, dass dem betreffenden Member Implementierung fehlt. Subklassen sind gezwungen, sich selbst als abstrakt zu deklarieren oder die fehlende Implementierung zu liefern. final kann vor allen Membern außer Konstruktoren stehen und bedeutet, dass der betreffende Member nicht mehr verändert werden darf. Finale Variablen sind ähnlich wie Konstanten, finale Methoden dürfen von Subklassen nicht überschrieben werden und von finalen Klassen darf man erst garkeine Subklassen bilden.

native kann nur vor Methoden stehen und bedeutet, dass die Implementierung der betreffenden Methode nicht in Java, sondern einer anderen Programmiersprache geschrieben wurde und von der Virtuellen Maschine über eine Laufzeitbibliothek (DLL oder SO) gelinkt werden muss.

strictfp kennzeichnet Klassen und Methoden, deren enthaltene Fließkommaoperationen streng nach IEEE ablaufen müssen.

package deklariert die Paket-Zugehörigkeit der nicht-geschachtelten Top-Level-Klassen einer Quelltextdatei.

import importiert Symbole (derzeit nur Klassen, ab 1.5 auch statische Member).

boolean, char, byte, short, int, long, float, double und void sind Typen. void ist der Nichtstyp, notwendig, um Methoden ohne Rückgabewerte zu kennzeichnen. Für die primitiven Typen: siehe oben.

try, catch, finally, throw, throws beziehen sich auf's Exception Handling. Mit throw wird eine Exception ausgelöst. Alle eventuell ausgelösten Exceptions einer Methode, die nicht von RuntimeException oder Error abstammen, müssen mit throws in der Deklaration der Methode (Signatur) angegeben werden. Mit try umschließt man einen Block, in dem eventuell eine Exception auftreten könnte. Mit catch fängt man nach einem try-Block die dort aufgetretene Exception ab, mit finally hängt man an einen try oder catch-Block einen Block für Aufräumarbeiten an (z.B. Schließen von Dateien).

class und interface dienen zur Deklaration eigener Typen: Klassen und Interfaces.

extends und implements dienen der Vererbung: extends der genetischen Erweiterungsvererbung von Klasse zu Klasse oder Interface zu Interface und implements der Implementierungsvererbung von Interface zu Klasse.

super und this beziehen sich im Objekt-Kontext auf das aktuelle Objekt in seinem tatsächlichen Morph (this) bzw. im Morph der Superklasse (super). this wird verwendet, um in Konstruktoren überladene Konstruktoren aufzurufen, um bei Membernamenskonflikten explizit auf die von weiter innen liegenden Membern verdeckten Member zu verweisen. super wird in Konstruktoren zum Aufruf des Superklassenkonstruktors und in überschreibenden Methoden zum Aufruf der überschriebenen Methode verwendet.

new reserviert für neue Objekte (inkl. Arrays) neuen Speicher auf dem Heap.

if, else, switch, case, default, while, do, for, break, continue sind für die imperative Syntax, dienen also der Bedingungsprüfung und Schleifensteuerung.

return liefert Werte an eine Methode zurück.

volatile ist ein Modifizierer für nicht-lokale Variablen und verbietet dem JIT-Compiler Registeroptimierungen auf diese Variable, weil mehrere Threads sie gleichzeitig verwenden könnten.

synchronized verwendet ein Objekt als Semaphor mit Lock-Pool und sorgt so dafür, dass an jeglicher mit synchronized an denselben Semaphor gebundener Code nur ein einziges Mal gleichzeitig ausgeführt werden kann. Alle anderen Threads, die solche Code-Blöck ausführen möchten, werden solange blockiert, bis der Semaphor wieder frei ist.

transient kennzeichnet nicht-persistente Variablen, die bei der Serialisierung nicht automatisch serialisiert werden dürfen.

instanceof ist ein Java-Operator, der prüft, ob ein Objekt Instanz eines Typs ist.

Abgrenzung zu anderen Sprachen

JavaScript

Java ist nicht mit der Programmiersprache JavaScript zu verwechseln, die ebenfalls in Web-Browsern verwendet wird. Sie hat eine ähnliche Syntax, kennt aber keine Vererbung. Objekte werden in JavaScript prototypenbasiert definiert. JavaScript ist, wie der Name sagt, eine reine Skriptsprache. Es existieren Implementationen vor allem in Web-Browsern, aber auch alleinstehende Ausführungsumgebungen sind vorhanden

C++

Im Gegensatz zu C++ fanden komplexe Konstrukte, wie Mehrfachvererbung oder Zeigerarithmetik in Java keinen Einzug. In Java fand man weniger fehleranfällige Lösungen. Auch um die Speicherverwaltung braucht man sich als Java-Entwickler in der Regel keine Gedanken zu machen, dies erledigt der so genannte Garbage Collector.

C#

C# kann als Kampfansage von Microsoft an Java gesehen werden. Mit der Spezifikation von C# hat Microsoft versucht, den Spagat zu schaffen zwischen dem kompletten Neuanfang einer Sprache und der leichten Integration bisher bestehender Komponenten und Wissens. Die Syntax von C# ist Java sehr ähnlich, konzeptuelle Unterschiede sind auch gering. Ein wichtiger Unterschied ist, dass C# keine Primitivtypen kennt, das heißt alles ist ein Objekt. In C# kann man auch Objekte und Methoden mit Attributen auszeichnen, um sie mit Funktionalität anzureichern. Von Microsoft wird C# nur unter Windows unterstützt.


Die nächsten Versionen der Sprache Java

Vermutlich noch 2003 wird die erste Beta von Java 1.5 erscheinen. Sie wird voraussichtlich über folgende Neuerungen in der Sprache Java verfügen:

Außerdem kann man davon ausgehen, dass sich Java im Laufe der Zeit zu einer der ersten aspektorientierten Programmiersprache wandeln wird.

Versionen

  • JDK 1.0, 1996
  • JDK 1.1, 1997
  • J2SDK SE 1.2, 1998 (ab diesem Zeitpunkt spricht man von der Java 2 Plattform und vom Java 2 Platform Software Development Kit Standard Edition)
  • J2SDK SE 1.3, 2000
  • J2SDK SE 1.4, 2002

Siehe auch

  • Entwicklungsumgebungen
    • Eclipse (Open source Entwicklungsumgebung für Java)
    • NetBeans (Open source Entwicklungsumgebung für Java)