Einführung in die Skripterstellung in Java, Teil 1

Auszug aus der Skripterstellung in Java: Sprachen, Frameworks und Muster .

Von Dejan Bosanac

Veröffentlicht von Addison Wesley Professional

ISBN-10: 0-321-32193-6

ISBN-13: 978-0-321-32193-0

Bis vor kurzem waren nur die Hardcore-Fans von Skripten auf der Java-Plattform begeistert, aber das war, bevor Sun die Unterstützung der JRE für dynamisch typisierte Sprachen wie Python, Ruby und JavaScript verstärkte. In diesem zweiteiligen Auszug aus dem bevorstehenden Scripting in Java: Sprachen, Frameworks und Muster (Addison Wesley Professional, August 2007) geht Dejan Bosanac näher darauf ein, was die meisten Skriptsprachen von einer Programmiersprache wie Java unterscheidet, und erklärt dann, warum Scripting ein ist zeitwürdige Ergänzung Ihrer Java-Programmierkenntnisse.

Einführung in die Skripterstellung in Java: Sprachen, Frameworks und Muster

Das Hauptthema dieses Buches ist die Synergie von Skripttechnologien und der Java-Plattform. Ich beschreibe Projekte, mit denen Java-Entwickler eine leistungsfähigere Entwicklungsumgebung erstellen können, sowie einige der Methoden, die das Erstellen von Skripten nützlich machen.

Bevor ich mich mit der Anwendung von Skripten in der Java-Welt befasse, fasse ich einige der Theorien zusammen, die hinter Skripten im Allgemeinen und ihrer Verwendung in der Informationstechnologie-Infrastruktur stehen. Dies ist das Thema der ersten beiden Kapitel des Buches und gibt uns einen besseren Überblick über die Skripttechnologie sowie darüber, wie diese Technologie innerhalb der Java-Plattform nützlich sein kann.

Zunächst müssen wir die Skriptsprachen definieren und ihre Eigenschaften beschreiben. Ihre Eigenschaften bestimmen maßgeblich die Rollen, in denen sie verwendet werden könnten (sollten). In diesem Kapitel erkläre ich, was der Begriff Skriptsprache bedeutet, und diskutiere deren grundlegende Merkmale.

Am Ende dieses Kapitels diskutiere ich die Unterschiede zwischen Skript- und Systemprogrammiersprachen und wie diese Unterschiede sie für bestimmte Rollen in der Entwicklung geeignet machen.

Hintergrund

Die Definition einer Skriptsprache ist unscharf und manchmal nicht mit der Verwendung von Skriptsprachen in der realen Welt vereinbar. Daher ist es eine gute Idee, einige der grundlegenden Konzepte zum Programmieren und Rechnen im Allgemeinen zusammenzufassen. Diese Zusammenfassung bietet eine Grundlage für die Definition von Skriptsprachen und die Erörterung ihrer Merkmale.

Fangen wir von vorne an. Prozessoren führen Maschinenbefehle aus , die Daten entweder in den Prozessorregistern oder im externen Speicher verarbeiten. Einfach ausgedrückt besteht ein Maschinenbefehl aus einer Folge von Binärziffern (0s und 1s) und ist spezifisch für den bestimmten Prozessor, auf dem er ausgeführt wird. Maschinenanweisungen bestehen aus dem Operationscode , der dem Prozessor mitteilt, welche Operation er ausführen soll, und Operanden, die die Daten darstellen, an denen die Operation ausgeführt werden soll.

Betrachten Sie beispielsweise die einfache Operation zum Hinzufügen eines in einem Register enthaltenen Werts zu dem in einem anderen Register enthaltenen Wert. Stellen wir uns nun einen einfachen Prozessor mit einem 8-Bit-Befehlssatz vor, bei dem die ersten 5 Bits den Operationscode darstellen (z. B. 00111 für die Addition von Registerwerten) und die Register durch ein 3-Bit-Muster adressiert werden. Wir können dieses einfache Beispiel wie folgt schreiben:

00111 001 010

In diesem Beispiel habe ich 001 und 010 verwendet, um die Register Nummer eins und zwei (R1 bzw. R2) des Prozessors zu adressieren.

Diese grundlegende Berechnungsmethode ist seit Jahrzehnten bekannt, und ich bin sicher, dass Sie damit vertraut sind. Verschiedene Arten von Prozessoren haben unterschiedliche Strategien hinsichtlich des Aussehens ihrer Befehlssätze (RISC- oder CISC-Architektur). Aus Sicht des Softwareentwicklers ist jedoch die einzige wichtige Tatsache, dass der Prozessor nur binäre Befehle ausführen kann. Unabhängig davon, welche Programmiersprache verwendet wird, ist die resultierende Anwendung eine Folge von Maschinenbefehlen, die vom Prozessor ausgeführt werden.

Was sich im Laufe der Zeit geändert hat, ist die Art und Weise, wie Personen die Reihenfolge erstellen, in der die Maschinenanweisungen ausgeführt werden. Diese geordnete Folge von Maschinenanweisungen wird als Computerprogramm bezeichnet . Da Hardware immer erschwinglicher und leistungsfähiger wird, steigen die Erwartungen der Benutzer. Der gesamte Zweck der Softwareentwicklung als wissenschaftliche Disziplin besteht darin, Mechanismen bereitzustellen, mit denen Entwickler komplexere Anwendungen mit dem gleichen (oder sogar noch geringeren) Aufwand wie zuvor erstellen können.

Der Befehlssatz eines bestimmten Prozessors wird als Maschinensprache bezeichnet . Maschinensprachen werden als Programmiersprachen der ersten Generation klassifiziert. Auf diese Weise geschriebene Programme sind normalerweise sehr schnell, da sie für die jeweilige Prozessorarchitektur optimiert sind. Trotz dieses Vorteils ist es für Menschen schwierig (wenn nicht unmöglich), große und sichere Anwendungen in Maschinensprachen zu schreiben, da Menschen nicht gut mit großen Folgen von Nullen und Einsen umgehen können.

Um dieses Problem zu lösen, begannen die Entwickler, Symbole für bestimmte Binärmuster zu erstellen, und damit wurden Assemblersprachen eingeführt. Assemblersprachen sind Programmiersprachen der zweiten Generation . Die Anweisungen in Assemblersprachen sind nur eine Ebene über den Maschinenanweisungen, da sie Binärziffern durch leicht zu merkende Schlüsselwörter wie ADD, SUB usw. ersetzen. Daher können Sie das vorhergehende einfache Anweisungsbeispiel in Assemblersprache wie folgt umschreiben:

ADD R1, R2

In diesem Beispiel stellt das ADD-Schlüsselwort den Operationscode des Befehls dar, und R1 und R2 definieren die an der Operation beteiligten Register. Selbst wenn Sie nur dieses einfache Beispiel betrachten, ist es offensichtlich, dass Assemblersprachen das Lesen von Programmen für den Menschen erleichtert und somit die Erstellung komplexerer Anwendungen ermöglicht haben.

Obwohl sie eher auf den Menschen ausgerichtet sind, erweitern Sprachen der zweiten Generation die Prozessorfähigkeiten in keiner Weise.

Geben Sie Hochsprachen ein , mit denen Entwickler sich in übergeordneten semantischen Formen ausdrücken können. Wie Sie vielleicht vermutet haben, werden diese Sprachen als Programmiersprachen der dritten Generation bezeichnet . Hochsprachen bieten verschiedene leistungsstarke Schleifen, Datenstrukturen, Objekte usw., wodurch es viel einfacher wird, viele Anwendungen mit ihnen zu erstellen.

Im Laufe der Zeit wurde eine Vielzahl von Programmiersprachen auf hoher Ebene eingeführt, deren Eigenschaften sehr unterschiedlich waren. Einige dieser Merkmale kategorisieren Programmiersprachen als Skriptsprachen (oder dynamische Sprachen), wie wir in den folgenden Abschnitten sehen werden.

Es gibt auch einen Unterschied darin, wie Programmiersprachen auf dem Host-Computer ausgeführt werden. Normalerweise übersetzen Compiler Sprachkonstrukte auf hoher Ebene in Maschinenanweisungen, die sich im Speicher befinden. Obwohl auf diese Weise geschriebene Programme anfangs etwas weniger effizient waren als in Assemblersprache geschriebene Programme, da frühe Compiler die Systemressourcen nicht effizient nutzen konnten, verbesserten sich Compiler und Maschinen im Laufe der Zeit und machten Systemprogrammiersprachen Assemblersprachen überlegen. Schließlich wurden Hochsprachen in einer Vielzahl von Entwicklungsbereichen populär, von Geschäftsanwendungen und Spielen bis hin zu Kommunikationssoftware und Betriebssystemimplementierungen.

Es gibt aber auch eine andere Möglichkeit, semantische Konstrukte auf hoher Ebene in Maschinenbefehle umzuwandeln, nämlich diese zu interpretieren, während sie ausgeführt werden. Auf diese Weise befinden sich Ihre Anwendungen in Skripten in ihrer ursprünglichen Form, und die Konstrukte werden zur Laufzeit von einem Programm namens Interpreter transformiert . Grundsätzlich führen Sie den Interpreter aus, der Anweisungen Ihrer Anwendung liest und diese dann ausführt. Diese als Skriptsprachen oder dynamische Sprachen bezeichneten Sprachen bieten einen noch höheren Abstraktionsgrad als die Systemprogrammiersprachen, auf die wir später in diesem Kapitel ausführlich eingehen.

Sprachen mit diesen Merkmalen eignen sich natürlich für bestimmte Aufgaben wie Prozessautomatisierung, Systemadministration und Zusammenkleben vorhandener Softwarekomponenten. Kurz gesagt, überall störten die strengen Syntax- und Einschränkungen, die durch Systemprogrammiersprachen eingeführt wurden, die Entwickler und ihre Jobs. Eine Beschreibung der üblichen Rollen von Skriptsprachen ist ein Schwerpunkt von Kapitel 2, "Geeignete Anwendungen für Skriptsprachen".

Aber was hat das alles mit Ihnen als Java-Entwickler zu tun? Um diese Frage zu beantworten, fassen wir zunächst kurz den Verlauf der Java-Plattform zusammen. Mit zunehmender Vielfalt der Plattformen wurde es für Entwickler immer schwieriger, Software zu schreiben, die auf den meisten verfügbaren Systemen ausgeführt werden kann. Zu diesem Zeitpunkt entwickelte Sun Java, das die Einfachheit "Einmal schreiben, überall ausführen" bietet.

Die Hauptidee hinter der Java-Plattform bestand darin, einen virtuellen Prozessor als Softwarekomponente zu implementieren, die als virtuelle Maschine bezeichnet wird . Wenn wir eine solche virtuelle Maschine haben, können wir den Code für diesen Prozessor anstelle der spezifischen Hardwareplattform oder des Betriebssystems schreiben und kompilieren. Die Ausgabe dieses Kompilierungsprozesses wird als Bytecode bezeichnet und repräsentiert praktisch den Maschinencode der virtuellen Zielmaschine. Wenn die Anwendung ausgeführt wird, wird die virtuelle Maschine gestartet und der Bytecode interpretiert. Es ist offensichtlich, dass eine auf diese Weise entwickelte Anwendung auf jeder Plattform mit einer geeigneten installierten virtuellen Maschine ausgeführt werden kann. Dieser Ansatz zur Softwareentwicklung fand viele interessante Anwendungen.

Die Hauptmotivation für die Erfindung der Java-Plattform war die Schaffung einer Umgebung für die Entwicklung einer einfachen, tragbaren und netzwerkfähigen Client-Software. Vor allem aufgrund der durch die virtuelle Maschine eingeführten Leistungseinbußen eignet sich Java jetzt am besten für die Entwicklung von Serversoftware. Es ist klar, dass mit zunehmender Geschwindigkeit von PCs immer mehr Desktop-Anwendungen in Java geschrieben werden. Dieser Trend setzt sich nur fort.

Eine der Grundvoraussetzungen für eine Skriptsprache ist ein Interpreter oder eine Art virtuelle Maschine. Die Java-Plattform wird mit der Java Virtual Machine (JVM) geliefert, mit der verschiedene Skriptsprachen gehostet werden können. Das Interesse der Java-Community an diesem Bereich wächst heute. Es gibt nur wenige Projekte, die versuchen, Java-Entwicklern die gleiche Leistung zu bieten, die Entwickler herkömmlicher Skriptsprachen haben. Es gibt auch eine Möglichkeit, Ihre vorhandene Anwendung, die in einer dynamischen Sprache wie Python geschrieben ist, in der JVM auszuführen und in eine andere Java-Anwendung oder ein anderes Java-Modul zu integrieren.

Dies ist, was wir in diesem Buch diskutieren. Wir verfolgen einen Skriptansatz für die Programmierung und diskutieren alle Stärken und Schwächen dieses Ansatzes, wie Skripte in einer Anwendungsarchitektur am besten verwendet werden und welche Tools heute in der JVM verfügbar sind.