Einloggen auf heise online

    • News
    • heise Developer
    • heise Netze
    • heise Open Source
    • heise Security
    • c't
    • iX
    • Technology Review
    • c't Fotografie
    • Mac & i
    • Make
    • Telepolis
    • heise Autos
    • TechStage
    • tipps+tricks
    • heise Download
    • Preisvergleich
    • Whitepapers
    • Webcasts
    • Stellenmarkt
    • Karriere Netzwerk
    • Gutscheine
    • IT-Markt
    • Tarifrechner
    • Netzwerk-Tools
    • Spielen bei Heise
    • heise shop
    • heise Select
    • Artikel-Archiv
    • Zeitschriften-Abo
    • Veranstaltungen
    • Arbeiten bei Heise
    • Mediadaten
ix-slogan-less-less-more-big
  • Kontakt
  • Forum
  • News
    • 7-Tage-News
    • News-Archiv
  • Heftartikel
    • Aktuelles Heft
    • Heftartikel lesen
    • Artikel-Archiv
  • Abo & Shop
    • Abonnieren
    • Einzelhefte kaufen
    • Heftarchiv auf DVD und USB-Stick
    • Sonderhefte
    • Video-Tutorials
    • iX extra
  • Apps
    • iOS
    • Android
    • Amazon-Store
    • FAQ zur iX-App
  • Veranstaltungen
  • Service
    • Listings/Downloads
    • Security-Awareness
    • Die iX-Redaktion
    • Newsletter
    • NiX Spam
    • Mediadaten
    • Presse-Informationen

  1. iX
  2. Heft
  3. 10/1996
  4. Kalter Kaffee

Kalter Kaffee

Rainer Fischbach
Inhaltsverzeichnis
  1. Kalter Kaffee
  2. Lücke im Java-Typsystem
  3. Abstrakte Datentypen und parametrische Module
  4. High-order-Funktionen
  5. Generics für Java
  6. Auf einer Seite lesen

Schaut man sich den Buchmarkt oder aktuelle Kongreßankündigungen an, dann scheint es künftig nur noch eine Programmiersprache zu geben. Dabei erfüllt Java - als Revolution gefeiert - keinesfalls die Kriterien, die an moderne und plattformunabhängige Programmiersprachen zu stellen sind.<br />

Wer sich Java genauer anschaut, bemerkt, daß die Sprache nichts Neues bietet. Das ist an sich kein Makel - schon die gelungene Kombination bekannter Merkmale kann Innovationscharakter haben. Doch reicht es nicht aus, nur anerkannt Gutes zusammenzufügen, um ein Produkt hervorzubringen, das die Bedürfnisse der Anwender befriedigt. Die Software muß den potentiellen Aufgabenbereich auch abdecken. Doch genau hier versagt Java.

Portabilität, Robustheit gegen Programmfehler, statische Typsicherheit und die Sicherheit des Gastsystems gegen bösartige Programme sind Eigenschaften, die Java von anderen Sprachen abheben soll. Das Sicherheitsproblem zieht bereits genug Aufmerksamkeit auf sich und soll hier kein Thema sein. Softwareportabilität steht seit Jahrzehnten als Zielsetzung hinter der Entwicklung höherer Programmiersprachen. Sie stellte eines der stärksten Argumente für den Einsatz von FORTRAN dar. Das UCSD-p-System mit UCSD-Pascal und UCSD-Basic erzielte Plattformunabhängigkeit sogar auf der Ebene des Binärcodes.

Das, was gegenwärtig so revolutionär erscheint an Java und Java-fähigen Web-Browsern, schreibt nur die vor einem Jahrzehnt unterbrochene Geschichte des UCSD-p-Systems fort. Eine einfach zu implementierende virtuelle Maschine führt den auf allen Plattformen identischen Instruktionscode im Byteformat aus. Letzteren erzeugen die Compiler aus den Hochsprachemodulen.

Ein auf die wesentlichen Funktionen reduziertes Betriebssystem, das weitgehend in der höheren Programmiersprache geschrieben ist und dessen API aus Modulschnittstellen dieser Sprache besteht, ergänzt die Maschine. Nur sollen die Programme und Daten nicht mehr von lokalen Datenträgern, sondern aus dem Netz kommen.

Die Java-Station, die nur noch Software ausführt, die sie in Form von Java-Bytecode vom Netz lädt, ist eine zeitgemäße Neuauflage des Konzepts der monolingualen Workstation, das Niklaus Wirth und seine Mitarbeiter vor beinahe 20 Jahren an der ETH Zürich zu realisieren begannen. Fünf Jahre später ging das Ergebnis, Lilith, eine Modula-2-Maschine, in Produktion.

Keine Pioniertaten von Sun

In vielen Projekten der 70er und frühen 80er Jahre fand sich die Idee des plattformunabhängigen Bytecodes. Im portablen Pascal-Compiler der ETH Zürich, auf den das UCSD-p-System zurückgeht [#lit01 [1]], in den Xerox-PARC-Entwicklungen Mesa und Smalltalk-80 [#lit02 [2], [#lit03 3]] und in EUMEL, um nur einige zu nennen.

Grüße aus den siebziger Jahren

Daß dieser Ansatz an der schlechten Performance gescheitert sein soll, kann nicht überzeugen. Es gab und gibt genug andere, recht erfolgreiche Zyklenfresser. Zudem gab es auch damals schon Mittel, um das Performance-Defizit zu beheben. Man kann den plattformunabhängigen Instruktionscode auf dem Zielsystem in Maschinencode umwandeln oder realisiert die virtuelle Maschine nicht durch ein Interpreter-Programm, sondern gießt sie in Silizium.

Die erste Möglichkeit boten schon die weiterentwickelten Versionen des UCSD-p-Systems. Letztere nimmt Sun jetzt mit der Java-Maschine wahr. Das ist jedoch keine Pioniertat, das gab es schon in Gestalt der Pascal Microengine von Western Digital für das UCSD-p-System, und auch das Lilith-Design wählte diese Alternative [#lit04 [4]].

Ein Umstand, der die Diskussion dieser Dinge erschwert, ist das weitverbreitete Unvermögen, zwischen einer Programmiersprache und ihrer Implementierung zu unterscheiden. Es gibt zwar Sprachen, die vorwiegend auf die eine oder andere Weise implementiert wurden, doch prinzipiell gibt es weder ÔInterpreter-Ô noch ÔCompilersprachenÕ.

Die Wahl zwischen verschiedenen Implementierungstechniken darf keinen Einfluß auf die Eigenschaften haben, die einer Programmiersprache qua Definition zukommen. Entscheidend ist immer nur, ob die Implementierung korrekt ist oder nicht. Die Behandlung von Ereignissen, die einen undefinierten Zustand involvieren, gehört strenggenommen nicht mehr zu dem, was innerhalb der Beschreibung einer algorithmischen Sprache spezifizierbar ist, sondern zur Beschreibung der Implementierung, hier: des Laufzeitsystems.

Vor Anbruch der PC-Zeit galt es als selbstverständlich, daß der Absturz eines Programms nicht den des Rechners nach sich ziehen darf. Es ging darum, die Ausführung illegaler Operationen zu blockieren, um die Anwenderprozesse voneinander und von den Systemprozessen zu isolieren. Multiprogramming-Systeme waren - in der Regel unterstützt durch die Hardware - dazu schon immer in der Lage.

Java verspricht, derartiges zu leisten, und viele verstehen das als Durchbruch. Leider zeigt sich hier eher der Verlust technischer Qualitätsmaßstäbe infolge der massenhaften Verbreitung konzeptionell fragwürdiger und höchst unzulänglich implementierter Programmiersprachen und Betriebssysteme.

Daß Java keine Pointer-Arithmetik zuläßt und Implementierungen über eine automatische Speicherverwaltung verfügen müssen, erscheint nur dann als Fortschritt, wenn man als Maßstäbe C und C++ heranzieht. Vielmehr sind das Anforderungen, die eine universell einsetzbare Programmiersprache erfüllen muß. Objektorientierte Sprachen wie Simula, Smalltalk, Eiffel und Beta sowie die funktionalen und logischen Sprachen entsprechen ihnen schon lange.

Mit dem Risiko von Laufzeitfehlern läßt sich auf verschiedene Weisen umgehen:

  • Die ausschließliche Verantwortung für fehlerhafte Software tragen die Programmierer.
  • Programmiersprachen und Entwicklungswerkzeuge ermöglichen es, möglichst viele Fehler schon vor der Programmausführung zu entdecken.
  • Das Laufzeitsystem unterbindet fehlerhafte Operationen, die nicht vorhersagbare Folgen haben können.

Die populärste Variante der zweiten Strategie bilden statische Typsysteme. Sie eliminieren eine umfangreiche Klasse von Fehlern. Eine weitergehende, doch bisher kaum erfolgreiche Variante derselben Strategie sind Programmbeweiser, weshalb die Notwendigkeit von Laufzeittests bestehenbleibt.

Großen Einfluß auf den Umfang der Fehler, die schon zur Übersetzungszeit erkennbar sind, hat die konkrete Ausformung des Typsystems. Pascal und ML sind in die Geschichte eingegangen als Sprachen, die in dieser Hinsicht Durchbrüche erzielt haben. Java, so heißt es, sei statisch typsicher und deshalb ein Meilenstein der Softwaregeschichte. Wie steht es mit dieser Behauptung?

Gleiches Problem, nur versteckt

Tatsächlich stellt die Typsicherheit objektorientierter Sprachen mit Vererbung eine besondere Herausforderung dar. Statische Typsicherheit ist hier nur um einen sehr hohen Preis erreichbar, und Java ist von diesem Ziel weit entfernt. Viele Techniken, die gerade die Attraktivität der objektorientierten Programmierung ausmachen, sind mit statischer Typkorrektheit - also dem vollständigen Nachweis derselben zur Übersetzungszeit - nur schwer zu vereinbaren. Beispielhaft dafür ist die mangelnde Typsicherheit, die aus der in Eiffel erlaubten Verfeinerung (Typeinschränkung) formaler Parameter von redefinierten Methoden resultiert.

Java verbietet es zwar, Methodenparameter bei der Redefinition einzuschränken und vermeidet dadurch scheinbar die Schwachstelle von Eiffel. Dafür gibt es andere Lücken. Neben dem in allen objektorientierten Sprachen gegebenen Problem der negativen Typrekursion - klassisches Beispiel: Dreieck erbt von Polygon die Methode fuege_ecke_hinzu Ð sind es vor allem die Type-casts (Typumwandlungen), die Java unsicher machen.

Irgendeine Form von Type-cast braucht man in jeder objektorientierten Sprache. Doch Java stellt diesbezüglich ein besonderes Problem dar, weil die Sprache aus einem falschen Purismus ihrer Schöpfer heraus unnötigen Anlaß zur Verwendung von Type-casts schafft.

Das offen sichtbare Problem, das die Einschränkung von Methodenparametern in Eiffel nach sich zieht, wandelt sich bei Java in ein verstecktes. Derselbe Effekt ist hier durch Type-casts erzielbar(siehe Kasten Lücke im Java-Typsystem).

Schwerster Mangel von Java sind die fehlenden parametrischen Module. Es gibt gute Gründe dafür, diesen einen höheren softwaretechnischen Rang als der Vererbung einzuräumen. Die Notwendigkeit solcher Module demonstrieren die Behältertypen wie Liste, Stack oder Schlange.

In einer Sprache, die statische Typsicherheit anstrebt, ist es sinnvoll, Behälter zu haben, deren Inhalt einem bestimmten Typ angehört, etwa eine Liste von Strings oder einen Stack von Symbolen. Andererseits haben alle Listen, alle Stacks et cetera unabhängig vom Inhaltstyp identische Merkmale. Es kommt hauptsächlich auf die Logik des Zugriffs an, nicht auf das, worauf zugegriffen wird.

Diese Logik ist für jeden Behältertyp durch ein einheitliches Schema beschreibbar. In einem solchen Schema kommt der Inhaltstyp nur als Parameter vor, der gegebenenfalls bestimmten Bedingungen genügen muß. Die Elemente einer Menge müssen identifizierbar sein, die eines binären Suchbaums eine Totalordnung aufweisen und so weiter.

Die speziellen Behältertypen entstehen, indem man den Parameter durch einen konkreten Typ ersetzt. Die Bedingungen sind durch die Anforderung formulierbar, daß der konkrete Typ bestimmte Operationen zuläßt, wie etwa den Vergleich; was bedeutet, daß er einen bestimmten abstrakten Typ implementiert (siehe Kasten Abstrakte Datentypen und parametrische Module).

Verzicht auf sprachliche Mittel

Um die Sprache möglichst einfach zu halten, haben die Java-Designer auf parametrische Module und damit auf eines der wichtigsten sprachlichen Mittel verzichtet, um statische Typsicherheit mit Codeökonomie zu verbinden. Steht dieses Mittel nicht zur Verfügung, gibt es nur die Wahl zwischen zwei schlechten Alternativen: Entweder die Vervielfältigung prinzipiell identischen Codes, indem für jeden Inhaltstyp jeweils spezielle Behältertypen definiert werden, oder die Aufgabe der statischen Typsicherheit, indem der allgemeinste Typ Ð in diesem Fall Object Ð als Inhaltstyp spezifiziert wird.

Mit der zweiten Alternative begibt man sich hinsichtlich der statischen Typsicherheit auf die Ebene von Smalltalk und anderen Sprachen ohne statisches Typsystem. Solche Sprachen brauchen keine parametrischen Module Ð die braucht man nur, wenn man den Quellcode mit soviel Typinformation versehen möchte, daß wesentliche Fehler schon zur Kompilierzeit erkennbar sind.

Leider gibt gerade eine Betrachtung von Strukturen mit Inhalt weiteren Anlaß zu Kritik. Die Iteration über Strukturen ist eine alltägliche Operation. In den meisten objektorientierten Sprachen hat sie drei unangenehme Begleiterscheinungen:

  • Die Notwendigkeit, den Verwendern solcher Strukturen die navigierende Iteration über ihren Inhalt zu ermöglichen, zwingt zu aufgeblähten Schnittstellen.
  • Navigierende Zugriffe sind meist inkompatibel mit Update-Operationen. Die Mischung beider kann zu Fehlern führen. Die Kombination von Navigation mit Parallelität verschärft das Problem.
  • Navigation unter Kontrolle der Routine, die die Struktur verwendet, führt zur Multiplikation prinzipiell identischen Codes.

Das erste Problem läßt sich umgehen, indem man solche Klassen mit Iterator-Methoden versieht. Fortschrittliche Sprachdesigns wie Clu und Theta [#lit05 [5], [#lit06 6]] bieten spezielle Iterator-Abstraktionen und Iterations-Anweisungen. Allerdings sind auch die recht unflexibel, da sie eine starre Abfolge der Verarbeitungsschritte vorgeben. Eine ebenso elegante wie flexible und sparsame Alternative bieten die High-order-Funktionen, die in funktionalen Sprachen selbstverständlich sind (siehe Kasten High-order-Funktionen).

Wenig innovativ, insgesamt ernüchternd

Effektive High-order-Funktionen verlangen, wenn statische Typsicherheit gewährleistet sein soll, ein parametrisches Typsystem, das auch Funktionen und Prozeduren als gleichberechtigte Datenobjekte umfaßt. Nur dann bilden sie stabile Abstraktionen. Die Smalltalk-Blocks stellen zwar eine Form von Funktionen dar, die sich wie Objekte behandeln lassen Ð zum Beispiel können sie als Parameter fungieren. Allerdings gibt es für sie keine expliziten Typen und vor allem keine statische Typüberprüfung.

Ingesamt ist die Bilanz von Java ernüchternd. Innovatives bietet die Sprache kaum. Vielmehr werden - immerhin vielversprechende Ð Ansätze aus den 70er Jahren wiederbelebt. Gegenüber heutigen Mainstream-Sprachen wie C und C++ gibt es gewisse Fortschritte. Hinsichtlich Programmiermethodik und Sicherheit ist ein Rückfall hinter den Stand der Technik zu verzeichnen.

Wenn sich Java in seiner heutigen Form durchsetzt, würde zum wiederholten Male ein Produkt, das weit unter dem Stand der Technik liegt, zu einem De-facto-Standard. Versuche, das zu verhindern, sind angezeigt. Dabei geht es nicht darum, das durchaus begrüßenswerte Konzept zu kippen, sondern aus Java vielleicht doch noch eine gescheite Sprache zu machen.

Es gibt genug Vorbilder, an denen man sich orientieren kann. Beispielsweise stellt Theta eine ausgereifte - und selbstverständlich parametrische - Typ- und Modulstruktur in den Mittelpunkt (siehe Kasten Generics für Java). Vielversprechend hört sich auch an, was Phil Wadler und Martin Odersky vorhaben [#lit07 [7]]: Eine Erweiterung von Java um die Essentials funktionaler Sprachen.

RAINER FISCHBACH

ist freiberuflicher Berater und Autor und außerdem als Dozent an den Berufsakademien Stuttgart (Technische Informatik) und Heidenheim (Wirtschaftsinformatik) tätig.

Literatur

[1] Niklaus Wirth; Recollections about the Development of Pascal; in: Thomas J. Bergin, Richard G. Gibson (Hrsg.); History of Programming Languages-II; New York, ACM Press 1996

[2] Butler Lampson; Personal Distributed Computing: The Alto and Ethernet Software; in: Adele Goldberg (Hrsg.); A History of Personal Workstations. New York, NY: ACM Press 988

[3] Glenn Krasner (Hrsg.); Smalltalk-80: Bits of History, Words of Advice; Reading, MA; Addison-Wesley 983

[4] Richard S. Ohran; Lilith and Modula-2. BYTE 8/1984, S. 181 - 192>

[5] Barbara Liskov, John Guttag; Abstraction and Specification in Program Development; Cambridge, MA; MIT Press 1986

[6] Barbara Liskov u. a.; Theta Reference Manual. Preliminary Version; Programming Methodology Group Memo 88. Cambridge, MA; MIT Laboratory for Computer Science 1995

[7] Phil Wadler, Martin Odersky; Pizza-Projekt

[8] Giuseppe Castagna; Covariance and Contravariance, Conflict without a Cause; ACM Transactions on Programming Languages and Systems; Mai 1995 (Bd. 17, Nr. 3), S. 431 - 447

[9] Luca Cardelli, Peter Wegner; Understanding Types, Data Abstraction, and Polymorphism; ACM Computing Surveys, Dezember 1985 (Bd. 17, Nr. 4), S. 471 - 522

[10] Mark Day, Robert Gruber, Barbara Liskov, Andrew C. Myers; Subtypes vs. Where Clauses; Constraining Parametric Polymorphism; OOPSLA '95; ACM SIGPLAN Notices; Oktober 1995 (Bd. 30, Nr. 10), S. 156

iX-TRACT
  • Die als universelle Programmiersprache für die Zukunft gefeierte Sprache Java bietet konzeptionell kaum etwas Neues.
  • Das Implementierungskonzept wärmt einige vielversprechende Ansätze aus den 70er Jahren auf. Insgesamt bleibt die Sprache aber hinter dem Stand der Technik zurück.
  • Gegen das Implementierungskonzept ist zwar nichts einzuwenden, doch sollten die Entwickler, um aus Java doch noch eine gescheite Sprache zu machen, sich beim Design an moderneren Vorbildern orientieren. Einige Tools sind eher Entwicklungsumgebungen denn Editoren.

Auf der nächsten Seite: Lücke im Java-Typsystem

Vorherige 1 2 3 4 5 Nächste
Kommentieren
https://www.heise.de/-505274 Drucken
Anzeige
Anzeige
iX-Link
Was ist ein iX-Link?
Anzeige
  • 5 IT-Trends, die Sie auf dem Schirm haben sollten
  • Arbeitgeber Bewerbungen: Heise Karriere-Netzwerk
  • enterJS: Die volle Bandbreite an JavaScript-Wissen
  • Unter der Lupe: Hardware für den Endgeräteschutz
  • Wie Endgeräteschutz die IT-Sicherheit verbessert
  • Geldanlage: von Mensch und Maschine profitieren
  • Special: DSGVO Ratgeber
  • Interessante Jobangebote - IT-Jobtag in Leipzig!
Video-Tutorial:

Mit C die Grundlagen moderner Programmiersprachen lernen

Siebenstündiges Video-Tutorial zum Download

Aktuelles Heft iX
Erhältlich ab dem 19.04.2018
  • Aktueller Inhalt
  • Autoren dieses Heftes
  • Titelmotiv dieser iX herunterladen
iX kaufen Abo Kiosk finden
Aktuelle Inhalte in der iX-App
Apps für iX

iX-App für Android, iOS und Kindle Fire

iX können Sie auch auf Tablets und Smartphones unter Android und iOS lesen – als Plus-Abonnent sogar ohne zusätzliche Kosten.

Die Apps gibt es im App Store, bei Google Play und im Amazon App Shop

Meistkommentiert
  • DSGVO: Deutsche Unternehmen schlecht vorbereitet
  • E-Mail-Verschlüsselung: Bewährt sich Autocrypt in der Praxis?
  • Datenschutz-Grundverordnung: Die wichtigsten Fragen auf einen Blick
  • Oracle stellt MySQL 8.0 bereit
  • CLOUD Act: Freude bei Cloud-Providern und Besorgnis bei US-Datenschützern
Meistgelesen
  • Datenschutz-Grundverordnung: Die wichtigsten Fragen auf einen Blick
  • Oracle stellt MySQL 8.0 bereit
  • E-Mail-Verschlüsselung: Bewährt sich Autocrypt in der Praxis?
  • DSGVO: Deutsche Unternehmen schlecht vorbereitet
  • Endspurt: Leitfaden gibt konkrete Hilfe für Umsetzung der DSGVO
Kommunikation und Netze

Verlagsbeilage: ITK — Produkte und Lösungen

Rechenzentren und Infrastruktur

Verlagsbeilage: Server, Kabel, Cloud-Computing.

Aus den News-Foren
  1. Re: Was nimmt man im Outlook-Umfeld derzeit? (GpgOL funktioniert ja nicht)
    Du hast natürlich noch die Möglichkeit das Ganze als Gateway Lösung zu machen und nur am Übergang internes externes Netz die Mails zentral zu…

    Forum:  E-Mail-Verschlüsselung: Bewährt sich Autocrypt in der Praxis?

    Kiria hat keinen Avatar
    von Kiria; vor 12 Stunden
  2. Re: Neben Windows läuft...
    Also ich war vorhin etwas länger auf der Dell-Seite - der Konfigurator bietet mir bei den Optiplex-Modellen ausschließlich Windows 10 Pro 64 Bit…

    Forum:  Precision, Latitude & OptiPlex: Neue Dell-Rechner fürs Büro

    epek hat keinen Avatar
    von epek; vor 12 Stunden
  3. Alle möglichen Berater wittern halt das Geld
    Und vermutlich hat die Hälfte der Berater selber nicht genug Ahnung, wird dir aber einen Vertrag präsentieren der zwar die Zahlung sicherstellt…

    Forum:  Datenschutz-Grundverordnung: Schutz vor Abmahnungen und Bußgeldern

    CoolAllo hat keinen Avatar
    von CoolAllo; vor 13 Stunden
Aktuelle Ausgabe weiter zum Heft
Abo weiter zum Abo
Apps weiter zu den Apps
Sonderheft weiter zum Sonderheft
  • News
    • 7-Tage-News
    • News-Archiv
  • Heftartikel
    • Aktuelles Heft
    • Heftartikel lesen
    • Artikel-Archiv
  • Abo & Shop
    • Abonnieren
    • Einzelhefte kaufen
    • Heftarchiv auf DVD und USB-Stick
    • Sonderhefte
    • Video-Tutorials
    • iX extra
  • Apps
    • iOS
    • Android
    • Amazon-Store
    • FAQ zur iX-App
  • Veranstaltungen
  • Service
    • Listings/Downloads
    • Security-Awareness
    • Die iX-Redaktion
    • Newsletter
    • NiX Spam
    • Mediadaten
    • Presse-Informationen
    • Kontakt
    • Mediadaten
    • Presse-Infos
  • Datenschutzhinweis
  • Impressum
  • Kontakt
  • Mediadaten
  • 347379
  • Content Management by InterRed
  • Copyright © 2018 Heise Medien