Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Komponenten, JavaBeans und Module
14 Die Klassenbibliothek
15 Einführung in die nebenläufige Programmierung
16 Einführung in Datenstrukturen und Algorithmen
17 Einführung in grafische Oberflächen
18 Einführung in Dateien und Datenströme
19 Einführung ins Datenbankmanagement mit JDBC
20 Einführung in <XML>
21 Testen mit JUnit
22 Bits und Bytes und Mathematisches
23 Die Werkzeuge des JDK
A Java SE-Paketübersicht
Stichwortverzeichnis


Download:

- Beispielprogramme, ca. 35,4 MB


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil 13 Komponenten, JavaBeans und Module
Pfeil 13.1 JavaBeans
Pfeil 13.1.1 Properties (Eigenschaften)
Pfeil 13.1.2 Einfache Eigenschaften
Pfeil 13.1.3 Indizierte Eigenschaften
Pfeil 13.1.4 Gebundene Eigenschaften und PropertyChangeListener
Pfeil 13.1.5 Veto-Eigenschaften – dagegen!
Pfeil 13.2 JavaFX Properties
Pfeil 13.2.1 javafx.beans-Paket mit XXXProperty-Klassen
Pfeil 13.2.2 Property-Veränderungen registrieren
Pfeil 13.2.3 Beans-Binding
Pfeil 13.2.4 Property-Schnittstelle und bindXXX(…)-Methoden
Pfeil 13.2.5 XXXProperty-Beziehungen (für Typ-Fetischisten) *
Pfeil 13.2.6 Ausblick
Pfeil 13.3 Klassenlader (Class Loader) und Klassenpfad
Pfeil 13.3.1 Klassenladen auf Abruf
Pfeil 13.3.2 JAR-Dateien
Pfeil 13.3.3 Woher die kleinen Klassen kommen: die Suchorte und spezielle Klassenlader
Pfeil 13.3.4 Setzen des Klassenpfades
Pfeil 13.4 Zum Weiterlesen
 

Zum Seitenanfang

13.3Klassenlader (Class Loader) und Klassenpfad Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Klassenlader ist dafür verantwortlich, eine Klasse zu laden. Aus der Datenquelle (im Allgemeinen einer Datei) liefert der Klassenlader ein Byte-Array mit den Informationen, die im zweiten Schritt dazu verwendet werden, die Klasse ins Laufzeitsystem einzubringen; das ist Linking. Es gibt vordefinierte Klassenlader und die Möglichkeit, eigene Klassenlader zu schreiben, um etwa verschlüsselte und komprimierte .class-Dateien aus Datenbanken zu laden.

 

Zum Seitenanfang

13.3.1Klassenladen auf Abruf Zur vorigen ÜberschriftZur nächsten Überschrift

Nehmen wir zu Beginn ein einfaches Programm mit zwei Klassen:

class Person {

static String NOW = java.time.LocalDateTime.now().toString();



public static void main( String[] args ) {

Dog wuffi = new Dog();

}

}



class Dog {

Person master;

}

Wenn die Laufzeitumgebung das Programm Person startet, muss sie eine Reihe von Klassen laden. Das tut sie dynamisch zur Laufzeit. Sofort wird klar, dass es zumindest Person sein muss. Wenn aber die statische main(String[])-Methode aufgerufen wird, muss auch Dog geladen sein. Und da beim Laden einer Klasse auch die statischen Variablen initialisiert werden, wird auch die Klasse LocalDateTime geladen.

Zwei weitere Dinge werden nach einiger Überlegung deutlich:

  • Wenn Dog geladen wird, bezieht es sich auf Person. Da Person aber schon geladen ist, muss es nicht noch einmal geladen werden.

  • Unsichtbar stecken noch andere referenzierte Klassen dahinter, die nicht direkt sichtbar sind. So wird zum Beispiel Object geladen, da implizit in der Klassendeklaration von Person steht: class Person extends Object. Auch String muss geladen werden, weil String einmal in der Signatur von main(String[]) vorkommt und es der Typ von now ist. Intern ziehen die Typen viele weitere Typen nach sich. String implementiert Serializable, CharSequence und Comparable, also müssen diese drei Schnittstellen auch geladen werden. Und so geht das weiter, je nach dem, welche Programmpfade abgelaufen werden. Wichtig ist aber, zu verstehen, dass diese Klassendateien so spät wie möglich geladen werden.

Im Beispiel mit den Klassen Person und Dog lädt die Laufzeitumgebung selbstständig die Klassen (implizites Klassenladen). Klassen lassen sich auch mit Class.forName(String) über ihren Namen laden (explizites Klassenladen).

[»]Hinweis

Um zu sehen, welche Klassen überhaupt geladen werden, lässt sich der virtuellen Maschine beim Start der Laufzeitumgebung ein Schalter mitgeben: -verbose:class. Dann gibt die Maschine beim Lauf alle Klassen aus, die sie lädt.

 

Zum Seitenanfang

13.3.2JAR-Dateien Zur vorigen ÜberschriftZur nächsten Überschrift

Große Sammlungen von Java-Klassendateien und Ressourcen werden in so genannten Java-Archiven, kurz JAR-Dateien, zusammengefasst. Diese Dateien sind im Grunde ganz normale ZIP-Archive mit einem besonderen Verzeichnis META-INF für Metadateien. Das JDK bringt im bin-Verzeichnis das Werkzeug jar zum Aufbau und Extrahieren von JAR-Dateien mit.

JAR-Dateien behandelt die Laufzeitumgebung wie Verzeichnisse von Klassendateien und Ressourcen. Wenn Java-Software ausgeliefert wird, dann bieten sich JAR-Dateien an, denn es ist einfacher, nur ein komprimiertes Archiv weiterzugehen als einen großen Dateibaum. Zudem haben Java-Archive den Vorteil, dass sie signiert werden können und illegale Änderungen auffallen.

 

Zum Seitenanfang

13.3.3Woher die kleinen Klassen kommen: die Suchorte und spezielle Klassenlader Zur vorigen ÜberschriftZur nächsten Überschrift

Die Laufzeitumgebung nutzt zum Laden nicht nur einen Klassenlader, sondern mehrere. Sie verwendet diese verschiedenen Klassenlader, um unterschiedliche Orte für die Klassendateien festzulegen. Ein festes Schema bestimmt die Suche nach den Klassen:

  1. Klassentypen wie String, Object oder Point stehen in einem ganz speziellen Archiv. Wenn ein eigenes Java-Programm gestartet wird, so sucht die virtuelle Maschine die angeforderten Klassen zuerst in diesem Archiv. Da es elementare Klassen sind, die zum Hochfahren eines Systems gehören, werden sie Bootstrap-Klassen genannt. Das Archiv mit diesen Klassen heißt oft rt.jar (für Runtime). Andere Archive können hinzukommen – wie i18n.jar, das Internationalisierungsdaten beinhaltet. Die Implementierung dieses Bootstrap-Klassenladers ist nicht öffentlich und wird von System zu System unterschiedlich sein. Ab Java 9 wird sich das grundlegend ändern.

  2. Ist eine Klasse keine Bootstrap-Klasse, beginnt der System-Klassenlader bzw. Applikations-Klassenlader die Suche im Klassenpfad (Classpath). Diese Pfadangabe besteht aus einer Aufzählung einzelner Klassendateien, Verzeichnisse, Klassen oder JAR-Archive, in denen die Laufzeitumgebung nach den Klassendateien sucht. Standardmäßig ist dieser Klassenpfad auf das aktuelle Verzeichnis gesetzt (».«), er lässt sich aber beliebig setzen.

 

Zum Seitenanfang

13.3.4Setzen des Klassenpfades Zur vorigen ÜberschriftZur nächsten Überschrift

Wo die JVM die Klassen findet, muss ihr mitgeteilt werden, und das ist in der Praxis elementar für die Auslieferung, auch englisch deployment genannt. Java wartet mit dem Laden der Klassen so lange, bis sie benötigt werden. Es gibt zum Beispiel Programmabläufe nur zu besonderen Bedingungen, und wenn dann erst spät ein neuer Typ referenziert wird, der nicht vorhanden ist, fällt dieser Fehler erst sehr spät auf. Der JVM müssen folglich nicht nur die Quellen für Klassen und Ressourcen der eigenen Applikation mitgeteilt werden, sondern alle vom Programm referenzierten Typen aus zum Beispiel quelloffenen und kommerziellen Bibliotheken.

Sollen in einem Java-Projekt Dateien aus einem Verzeichnis oder einem externen Java-Archiv geholt werden, so ist der übliche Weg, diese Verzeichnisse oder Archive in einem Klassenpfad anzugeben. Diese Angabe ist für alle SDK-Werkzeuge notwendig – am häufigsten ist sie beim Compiler und bei der Laufzeitumgebung zu sehen.

Schalter -classpath

Die Suchorte lassen sich flexibel angeben, wobei die erste Variante einem SDK-Werkzeug über den Schalter -classpath (kurz -cp) die Klassendateien bzw. Archive liefert:

$ java -classpath classpath1;classpath2 MainClass

Der Klassenpfad enthält Wurzelverzeichnisse der Pakete und JAR-Dateien, also Archive von Klassendateien und Ressourcen.

[zB]Beispiel

Nimm ein Java-Archiv library.jar im aktuellen Verzeichnis, die Ressourcen unter dem bin-Verzeichnis und alle JAR-Dateien im Verzeichnis lib in den Klassenpfad mit auf:

$ java -cp "library.jar;bin/.;lib/*" com.tutego.MainClass

Unter Windows ist der Trenner ein Semikolon, unter Unix ein Doppelpunkt! Das Sternchen steht für alle JAR-Dateien, es ist keine übliche Wildcard, wie z. B. parser*.jar.[ 218 ](Weitere Details unter https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html) Sehen Kommandozeilen der Betriebssysteme ein *, beginnen sie in der Regel eine eigene Verarbeitung; daher muss die gesamte Pfadangabe in doppelten Anführungszeichen stehen.

Umgebungsvariable CLASSPATH

Eine Alternative zum Schalter -cp ist das Setzen der Umgebungsvariablen CLASSPATH mit einer Zeichenfolge, die Pfadangaben spezifiziert:

$ SET CLASSPATH=classpath1;classpath2

$ java MainClass

Problematisch ist der globale Charakter der Variablen, sodass lokale -cp-Angaben besser sind. Außerdem »überschreiben« die -cp-Optionen die Einträge in CLASSPATH. Zu guter Letzt: Ist weder CLASSPATH noch eine -cp-Option gesetzt, besteht der Klassenpfad für die JVM nur aus dem aktuellen Verzeichnis, also ».«.

inline Um in Eclipse den Klassenpfad zu erweitern, damit etwa die Klassendateien von Java-Archiven berücksichtigt werden, ist Folgendes zu tun: Im Projekt das Kontaktmenü öffnen und Properties aufrufen, dann links unter Java Build Path gehen und anschließend im Reiter Libraries entweder Add JARs… (JARs sind im Projekt) oder Add External JARs… (JAR-Dateien liegen nicht im Projekt, sondern irgendwo anders im Dateisystem) nutzen.

[»]Hinweis

Die so genannten Bootstrap-Klassen aus den Paketen java.* (wie Object, String), com.sun.* usw. stehen nicht im CLASSPATH. Wer den Pfad für die Bootstrap-Klassen ändern möchte, kann dies mit dem Schalter -Xbootclasspath tun.

Classpath-Hell

Java-Klassen in JAR-Dateien auszuliefern ist der übliche Weg, es gibt aber zwei Probleme:

  1. Aus Versehen können zwei JAR-Dateien mit unterschiedlichen Versionen im Klassenpfad sein. Nehmen wir an, es sind parser-1.2.jar und parser-2.0.jar, wobei sich bei der neuen Version die API und Implementierung etwas geändert haben. Das fällt vielleicht am Anfang nicht auf, denn einen Ladefehler gibt es für den Typ nicht, er ist ja da – die JVM nimmt den ersten Typ, den sie findet. Nur wenn ein Programm auf die neue API zurückgreift, aber die geladene Klasse vom alten JAR stammt, knallt es zur Laufzeit. Bei doppelten JARs mit unterschiedlichen Versionen führt eine Umsortierung im Klassenpfad zu einem ganz anderen Ergebnis. Zum Glück lässt sich das Problem relativ schnell lösen.

  2. Zwei Java-Bibliotheken – nennen wir sie vw.jar und audi.jar – benötigen je eine Neben-JAR zum Arbeiten. Doch während vw.jar die Version bosch-1.jar benötigt, benötigt audi.jar die Version bosch-2.jar. Das ist ein Problem, denn JARs sind im Standard-Klassenpfad immer global, aber nicht hierarchisch, es kann also kein JAR eine »lokale« Unter-JAR haben.

Lösungen für das zweite Problem gibt es einige, wobei zu neuen Klassenladern gegriffen wird. Bekannt ist OSGi, das in der Java-Welt aber etwas an Fahrt verloren hat. Auch Oracle hat das Problem erkannt und entwickelt für Java 9 ein Modulsystem.

Modulsystem in Java 9

Java 9 beschreibt ein Modul

  1. mit einem Namen,

  2. was es wem exportiert und

  3. was es benötigt.

Interessant ist der zweite Aspekt, dass ein Modul etwas exportiert. Wenn nichts exportiert wird, ist auch nichts sichtbar nach außen. Alles, was Außenstehende sehen sollen, muss in der Modulbeschreibung aufgeführt sein – nicht alle öffentlichen Typen des Moduls sind standardmäßig öffentlich, dann wäre das kein Fortschritt zu JAR-Dateien. Mit dem neuen Modulsystem haben wir also eine ganz andere Sichtbarkeit. Aus der Viererbande public, private, paketsichtbar, protected bekommt public eine viel feinere Abstufung. Denn was public ist, bestimmt das Modul, und das sind

  • Typen, die das Modul für alle exportiert,

  • Typen für explizit aufgezählte Module,

  • alle Typen im gleichen Modul.

Der Compiler und die JVM achten auf die Einhaltung der Sichtbarkeit, und auch Tricks mit Reflection sind nicht mehr möglich, wenn ein Modul keine Freigabe erteilt hat.

[zB]Beispiel

Die Modulinformationen werden über eine Datei module-info.java deklariert, Annotationen kommen nicht zum Einsatz:

module com.tutego.csv {

exports com.tutego.csv.api;

requires com.tutego.parser;

}

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
 Zum Katalog
Zum Katalog: Java ist auch eine Insel Java ist auch eine Insel

Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?

Ihre Meinung



 Buchempfehlungen
Zum Katalog: Java ist auch eine Insel

Java ist auch eine Insel




Zum Katalog: Java SE 9-Standard-Bibliothek

Java SE 9-Standard-Bibliothek




Zum Katalog: Professionell entwickeln mit Java EE 8

Professionell entwickeln mit Java EE 8




Zum Katalog: Entwurfsmuster

Entwurfsmuster




Zum Katalog: IT-Projektmanagement

IT-Projektmanagement




 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2017

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de