ATOS - Around The Operating System Das ATOS-Magazin 4/96

# Von ObjectGEM zu Java

Inhaltsübersicht:
Einleitung
Hello World
Die Datei "HELLO.PAS"
Die Datei "HelloWorld.java"
Der Vergleich
Finale
Literatur

### Java: Einleitung

Java ist in aller Munde. Nicht nur in denen der Programmierer von Sun Microsystems bzw. JavaSoft, die ihre neue Sprache nach ihrem Lieblingsgetränk benannt haben, sondern auch bei den Anwendern und Programmierern in der ganzen großen weiten Welt des Internet. Java ist Grund und Grundlage wildester Spekulationen. Java ist eines der wenigen Produkte, die Microsoft lizenziert, ohne gleich die zugehörige Firma aufzukaufen. Java ist der Hype schlechthin.

Daß Java wirklich kein kalter Kaffee ist, sondern von jedem selbst frisch aufgebrüht werden kann, soll der folgende kurze Vergleich eines ObjectGEM- und Java-Sourcecodes zeigen. Auch wenn ObjectGEM nicht jedem bekannt ist, ist die Sprache dieser Bibliothek - PurePascal - vielen sicherlich nicht unbekannt, und ein Pascalprogramm allgemein werden die meisten wohl schon gesehen haben. Daher gebe ich im folgenden nur einen kurzen Überblick über Java.

Java ist eine

- einfache

  Es gibt relativ wenig Sprachkonstrukte. Die Sprache sieht für C- und C++-Programmierer "bekannt" aus, ohne daß der Overhead von C++ (nette Spielereien, die aber kaum jemand nutzt bzw. Konstrukte, die zur unübersichtlichen und fehleranfälligen Programmierung ermuntern) übernommen wurde. Und es gibt keine (!) Pointer.

- objektorientierte

  Java ist komplett objektorientiert (wie z.B. Eiffel), hybride Programmierung wie in C++ oder ObjektPascal ist nicht möglich.

- verteilte

  Java ist dafür vorbereitet, im Netz (sei es im Internet oder in einem betriebsinternen Intranet) zu arbeiten und Ressourcen (Dateien, Bilder, Sounds) von dort anzufordern.

- interpretierte

  Java-Sourcecodes werden zum sogenannten "Bytecode" compiliert. Dies ist eine Art prozessorunabhängige Maschinensprache, die vom Java-Interpreter (z.B. javai aus dem Java Development Kit von Sun) interpretiert wird.

  Mittlerweile wird allerdings an Java-Inlinecompilern (JILs) gearbeitet, die Java-Bytecode zur Laufzeit in echten (d.h. prozessorabhängigen) Maschinencode übersetzen.

- robuste

  Mit Java ist es leichter möglich, zuverlässige Software zu schreiben, wofür verschiedene Sprachkonstrukte zur Verfügung stehen. Ausgeschlossen werden können Programmierfehler natürlich nicht.

- sichere

  Java ist eine sichere Sprache, d.h. sie ist gegen Hackversuche aus dem Netz (Manipulation eines Rechners von außen) geschützt.

  Die Sicherheitsbedenken, die durch die Netze geisterten, betrafen ausschließlich die fehlerhafte Java-Implementation in einer Netscape 2.x-Version, nicht aber die Sprache an sich.

- architekturneutrale

  Abgesehen vom prozessorunabhängigen Bytecode sind sämtliche Zugriffe auf Systemressourcen (Fenster, Dialoge etc.) standardisiert.

- portable

  Zusätzlich zur Architekturneutralität sind auch solch grundlegenden Dinge wie der Aufbau und die Größe von elementaren Datentypen festgelegt, so daß der Bytecode zwischen allen Rechnerwelten portabel ist.

- high-performance

  Obwohl Java eine interpretierte Sprache ist, ist sie nur um etwa den Faktor 20 langsamer als übliche C-Programme. Dieser Wert relativiert sich zudem, da der Prozessor bei einer grafischen Benutzeroberfläche die meiste Zeit mit Warten verbringt.

  Ferner ist der Java-Bytecode so ausgelegt, möglichst optimal in prozessorabhängigen Maschinencode übersetzt werden zu können.

- multithreaded

  MiNT hat es eingeschränkt, MagiC bietet es jetzt auch (und dafür gleich besser), bei Java ist es von Anfang an mit dabei: Threads. Man kann in Java ohne großen Aufwand mehrere Aktionen nebenläufig ablaufen lassen - um die meisten kritischen Sachen kümmert sich Java automatisch.

- dynamische

  Klassen werden nur bei Bedarf nachgeladen.

Sprache.

Im folgenden kleinen Einblick können nicht alle dieser Eigenschaften erläutert werden, aber zumindest die Einfachheit und Objektorientierung sollten deutlich werden.

### Hello World

Java wäre keine ernstzunehmende Programmiersprache, wenn man mit ihr nicht auch das klassische Testprogramm schreiben könnte - Hello World!

Ein jeder kennt dieses Programm, seine Funktionsweise, und der Sourcecode ist auch für Nichtkenner einer Sprache ohne größere Probleme lesbar.

Zunächst sind die kompletten Sourcecodes aufgelistet, danach kommt der versprochene Vergleich.

### Die Datei "HELLO.PAS"

    program Hello;

    uses

      Gem,OTypes,OWindows;

    type

      TMyApplication = object(TApplication)
        procedure InitMainWindow; virtual;
      end;

      PMyWindow = ^TMyWindow;
      TMyWindow = object(TWindow)
        procedure Paint(var PaintInfo: TPaintStruct); virtual;
      end;

    var

      MyApp: TMyApplication;

    procedure TMyApplication.InitMainWindow;

      begin
        new(PMyWindow,Init(nil,''))
      end;

    procedure TMyWindow.Paint(var PaintInfo: TPaintStruct);

      begin
        v_gtext(vdiHandle,Work.X+10,Work.Y+20,'Hello World!')
      end;

    begin
      MyApp.Init('HelloWorld');
      MyApp.Run;
      MyApp.Done
    end.

### Die Datei "HelloWorld.java"

    import java.awt.*;

    public class HelloWorld
    {

      public static void main(String args[])
      {
        MyFrame f = new MyFrame();

        f.resize(200,100);
        f.show();
      }

    }

    public class MyFrame extends Frame
    {

      public MyFrame()
      {
        super("");
      }

      public void paint(Graphics g)
      {
        g.drawString("Hello World!",10,20);
      }

    }

### Der Vergleich

Als erstes fällt sofort ins Auge, daß das Java-Programm nicht so sehr wie ein Pascal-, sondern vielmehr wie ein C- oder C++-Programm aussieht. Dennoch ist ein Vergleich zwischen Java und PurePascal nicht abwegig, denn beide erlauben objektorientierte Programmierung - Java zwingt den Programmierer sogar dazu.

Los geht's mit der ersten Zeile des Pascal-Programms: `program Hello;`. Bei Pascal ist die Zeichenkette hinter `program` ziemlich egal, kaum ein Compiler erwartet hier spezielle Angaben. Der Name der späteren Programmdatei wird meistens aus dem Namen der Sourcecodedatei erzeugt (also z.B. "HELLO.PRG" aus "HELLO.PAS"), dieser hat mit der Ausführung des Programms aber nichts zu tun.

In Java fehlt eine entsprechende Zeile, außerdem sind die Dateinamen viel enger mit dem Sourcecode verknüpft. Aus dem obigen Java-Sourcecode würden z.B. die beiden Klassen "HelloWorld.class" und "MyFrame.class" erzeugt bzw. - wenn alle zu einem Projekt gehörenden Klassen zu einer ausführbaren Datei zusammengelinkt werden - die Datei "HelloWorld.out", da dies die Klasse mit der `main()`-Methode ist.

Danach werden die nötigen Bibliotheken eingebunden: `Gem` (AES- und VDI-Aufrufe), `OTypes` (ObjectGEM-Konstanten und -Typen) und `OWindows` (die nötigen ObjectGEM-Objekte) bei PurePascal, alle `java.awt`-Klassen ("advanced windowing toolkit", Klassen zur systemunabhängigen Fenster- und Dialogdarstellung) bei Java.

Anschließend folgt bei Pascal die Deklaration der Objekte, ein Applikationsobjekt (`TMyApplication`) und ein Fensterobjekt (`TMyWindow`). Bei Java fehlt ein solcher Deklarationsteil, die Deklaration geschieht direkt bei der Implementation der Objekte. Eine getrennte Deklaration ist auch gar nicht nötig, da alle Methoden an allen Stellen des Programms aufgerufen werden können (`forward` ist also überflüssig), wenn sie nicht explizit vor einem Zugriff geschützt werden. Neben den von Pascal bekannten Schlüsselwörtern `public` und `private` kann man in Java die Zugriffsrechte allerdings noch wesentlich genauer differenzieren. Zu bemerken ist noch, daß auch bei Java ein Art "Applikationsobjekt" (`HelloWorld`) und ein Fensterobjekt (`MyFrame`) angelegt wird.

In der folgenden Zeile instantiiert Pascal dann das Applikationsobjekt (`var MyApp: TMyApplication;`), der Aufruf geschieht mit den drei Methoden `Init()`, `Run` und `Done` im Hauptprogramm am Ende des Quelltextes. In Java wird das Objekt mit der `main()`-Methode automatisch instantiiert, und diese Methode wird ebenfalls automatisch aufgerufen (`main()` ist - analog zu C und C++ - das eigentliche Hauptprogramm).

In der überschriebenen Methode von `TApplication`, `InitMainWindow`, wird das Fensterobjekt vom Typ `TMyWindow` schließlich erzeugt und das Fenster implizit geöffnet. Genauso wird in `main()` das Fensterobjekt vom Typ `MyFrame` erzeugt, muß danach allerdings explizit geöffnet werden (`f.show();`).

War diese Aktion schon recht ähnlich, wird es jetzt nahezu gleich: Die Ausgabe der Zeichenkette "Hello World!" wird in den jeweiligen `Paint`-Methoden vorgenommen. Der Grafikkontext (Clipping etc.) - bei ObjectGEM als `vdiHandle` übergeben, bei Java beschreibt `g` selbst den Kontext - ist vor dem Aufruf passend eingerichtet, so daß innerhalb der Methoden nur noch die Textausgaberoutine aufgerufen werden muß.

Mehr gibt es im direkten Vergleich der Quelltexte eigentlich nicht zu sehen, wenn man nicht auch noch die Sprachsyntax mit einbezieht. Drei wesentliche Punkte möchte ich davon dann doch noch erwähnen.

In Pascal geschieht Vererbung bei der Typendeklaration des Objekts, bei unserem Beispiel `type TMyWindow = object(TWindow) ... end;`, der Ableitungsoperator ist hierbei `object()`. Bei Java übernimmt diese Rolle `extends`, ansonsten sieht die Vererbung der von Pascal recht ähnlich: `class MyFrame extends Frame { ... }`.

Beide Sprachen haben gemeinsam, daß sie Mehrfachvererbung nicht unterstützen, ein Objekt kann also immer nur von genau einem Objekt abgeleitet werden, kann also nur genau einen Vorfahren haben. Java erlaubt allerdings die Verwendung sogenannter "interfaces" in beliebiger Zahl. Dies sind keine Objekte bzw. Klassen, sondern Schnittstellendefinitionen (abstrakte Methodendeklarationen), die eine das Interface verwendende Klasse implementieren muß.

Außerdem nicht ganz offensichtlich ist, daß Pascal standardmäßig statische Methoden verwendet, die durch das Schlüsselwort `virtual` virtuell gemacht werden können. In Java dagegen sind alle Methoden virtuell, wenn sie nicht mit `static` explizit statisch ausgelegt werden.

Zum Abschluß gibt es noch ein bißchen Statistik:

| ObjectGEM | Java
Programmgröße | 160 KB | 6 KB, zzgl.
|  | 1.5 MB vorinstallierter
|  | Klassenbibliotheken
Compilerzeit | 2 Sekunden | 25 Sekunden

### Finale

Das war's dann auch schon. Mehr als ein Überblick konnte/sollte dieser Artikel nicht sein, aber wer auf den (Java-)Geschmack gekommen und des Englischen mächtig ist, findet in dem sehr zu empfehlenden Buch "Java in a Nutshell" alle weiteren Informationen.

Bleibt mir nur noch zu erwähnen, daß es einen Java-Interpreter bzw. -Compiler leider (noch?) nicht für GEM gibt. Sollte jetzt der eine oder andere Programmierer aufgeschreckt sein: Die (ANSI-C- bzw. Java-)Sourcen gibt es bei Sun, viel Spaß beim Portieren!

TM

### Literatur

- Dave Flanagan, "Java in a Nutshell", O'Reilly & Associates, Inc. (erste Auflage, Februar 1996)

- James Gosling, Henry McGilton, "The Java Language Environment - A White Paper", Sun Microsystems, (Oktober 1995)

- Sun Microsystems, "The Java Language Specification, Version 1.0 Beta", (Oktober 1995)

- Thomas Much, "Das ObjectGEM Programmierhandbuch Version 1.20", (November 1994)

- Thomas Much, "Die Dokumentation zu ObjectGEM 1.50", (pre-release)