Rheinwerk Computing < openbook >


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


Download:

- Listings, ca. 2,7 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 15 Die Klassenbibliothek
Pfeil 15.1 Die Java-Klassenphilosophie
Pfeil 15.1.1 Modul, Paket, Typ
Pfeil 15.1.2 Übersicht über die Pakete der Standardbibliothek
Pfeil 15.2 Einfache Zeitmessung und Profiling *
Pfeil 15.3 Die Klasse Class
Pfeil 15.3.1 An ein Class-Objekt kommen
Pfeil 15.3.2 Eine Class ist ein Type
Pfeil 15.4 Klassenlader
Pfeil 15.4.1 Die Klasse java.lang.ClassLoader
Pfeil 15.5 Die Utility-Klassen System und Properties
Pfeil 15.5.1 Speicher der JVM
Pfeil 15.5.2 Anzahl der CPUs bzw. Kerne
Pfeil 15.5.3 Systemeigenschaften der Java-Umgebung
Pfeil 15.5.4 Eigene Properties von der Konsole aus setzen *
Pfeil 15.5.5 Zeilenumbruchzeichen, line.separator
Pfeil 15.5.6 Umgebungsvariablen des Betriebssystems
Pfeil 15.6 Sprachen der Länder
Pfeil 15.6.1 Sprachen in Regionen über Locale-Objekte
Pfeil 15.7 Wichtige Datum-Klassen im Überblick
Pfeil 15.7.1 Der 1.1.1970
Pfeil 15.7.2 System.currentTimeMillis()
Pfeil 15.7.3 Einfache Zeitumrechnungen durch TimeUnit
Pfeil 15.8 Date-Time-API
Pfeil 15.8.1 Menschenzeit und Maschinenzeit
Pfeil 15.8.2 Die Datumsklasse LocalDate
Pfeil 15.9 Logging mit Java
Pfeil 15.9.1 Logging-APIs
Pfeil 15.9.2 Logging mit java.util.logging
Pfeil 15.10 Maven: Build-Management und Abhängigkeiten auflösen
Pfeil 15.10.1 Beispielprojekt in Eclipse mit Maven
Pfeil 15.10.2 Properties hinzunehmen
Pfeil 15.10.3 Dependency hinzunehmen
Pfeil 15.10.4 Lokales und das Remote-Repository
Pfeil 15.10.5 Lebenszylus, Phasen und Maven-Plugins
Pfeil 15.10.6 Archetypes
Pfeil 15.11 Zum Weiterlesen
 

Zum Seitenanfang

15.3    Die Klasse Class Zur vorigen ÜberschriftZur nächsten Überschrift

Angenommen, wir wollen einen Klassen-Browser schreiben. Dieser soll alle zum laufenden Programm gehörenden Klassen und darüber hinaus weitere Informationen anzeigen, wie etwa Variablenbelegung, deklarierte Methoden, Konstruktoren und Informationen über die Vererbungshierarchie. Dafür benötigen wir die Bibliotheksklasse Class. Exemplare der Klasse Class sind Objekte, die entweder eine Java-Klasse oder Java-Schnittstelle repräsentieren. (Dass auch Schnittstellen durch Class-Objekte repräsentiert werden, wird im Folgenden nicht mehr ausführlich erwähnt.)

In diesem Punkt unterscheidet sich Java von vielen herkömmlichen Programmiersprachen, da sich Eigenschaften von Klassen vom gerade laufenden Programm mithilfe der Class-Objekte abfragen lassen. Bei den Exemplaren von Class handelt es sich um eine eingeschränkte Form von Meta-Objekten[ 236 ](Echte Metaklassen wären Klassen, deren jeweils einziges Exemplar die normale Java-Klasse ist. Dann wären etwa die normalen Klassenvariablen in Wahrheit Objektvariablen in der Metaklasse. ) – die Beschreibung eines Java-Typs, die aber nur ausgewählte Informationen preisgibt. Neben normalen Klassen werden auch Schnittstellen durch ein Class-Objekt repräsentiert, und sogar Arrays und primitive Datentypen – statt Class wäre wohl der Klassenname Type passender gewesen.

 

Zum Seitenanfang

15.3.1    An ein Class-Objekt kommen Zur vorigen ÜberschriftZur nächsten Überschrift

Zunächst müssen wir für eine bestimmte Klasse das zugehörige Class-Objekt in Erfahrung bringen. Class-Objekte selbst kann nur die JVM erzeugen. Wir können das nicht (die Objekte sind immutable, und der Konstruktor ist privat).[ 237 ](Und in der Javadoc heißt es: »Constructor. Only the Java Virtual Machine creates Class objects.« ) Um einen Verweis auf ein Class-Objekt zu bekommen, bieten sich folgende Lösungen an:

  • Ist ein Exemplar der Klasse verfügbar, rufen wir die getClass()-Methode des Objekts auf und erhalten das Class-Exemplar der zugehörigen Klasse.

  • Jeder Typ enthält eine statische Variable mit dem Namen .class vom Typ Class, die auf das zugehörige Class-Exemplar verweist.

  • Auch auf primitiven Datentypen ist das Ende .class erlaubt. Das gleiche Class-Objekt liefert die statische Variable TYPE der Wrapper-Klassen. Damit ist int.class == Integer.TYPE.

  • Die Klassenmethode Class.forName(String) kann eine Klasse erfragen, und wir erhalten das zugehörige Class-Exemplar als Ergebnis. Ist der Typ noch nicht geladen, sucht und bindet forName(String) die Klasse ein. Weil das Suchen schiefgehen kann, ist eine ClassNotFoundException möglich.

  • Haben wir bereits ein Class-Objekt, sind aber nicht an ihm, sondern an seinen Vorfahren interessiert, so können wir einfach mit getSuperclass() ein Class-Objekt für die Oberklasse erhalten.

Das folgende Beispiel zeigt drei Möglichkeiten auf, um an ein Class-Objekt für java.util.Date heranzukommen:

Listing 15.2    src/main/java/com/tutego/insel/meta/GetClassObject.java, main()

Class<Date> c1 = java.util.Date.class;

System.out.println( c1 ); // class java.util.Date

Class<?> c2 = new java.util.Date().getClass();

// oder Class<? extends Date> c2 = ...



System.out.println( c2 ); // class java.util.Date

try {

Class<?> c3 = Class.forName( "java.util.Date" );

System.out.println( c3 ); // class java.util.Date

}

catch ( ClassNotFoundException e ) { e.printStackTrace(); }

Die Variante mit forName(String) ist sinnvoll, wenn der Name der gewünschten Klasse bei der Übersetzung des Programms noch nicht feststand. Sonst ist die vorhergehende Technik eingängiger, und der Compiler kann prüfen, ob es den Typ gibt. Eine volle Qualifizierung ist nötig, Class.forName("Date") würde nur nach Date in dem Default-Paket suchen – die Rückgabe ist ja keine Sammlung.

[zB]  Beispiel

Klassenobjekte für primitive Elemente liefert forName(String) nicht! Die beiden Anweisungen Class.forName("boolean") und Class.forName(boolean.class.getName()) führen zu einer ClassNotFoundException.

class java.lang.Object
  • final Class<? extends Object> getClass()

    Liefert zur Laufzeit das Class-Exemplar, das die Klasse des Objekts repräsentiert.

final class java.lang.Class<T>

implements Serializable, GenericDeclaration, Type, AnnotatedElement
  • static Class<?> forName(String className) throws ClassNotFoundException

    Liefert das Class-Exemplar für die Klasse oder Schnittstelle mit dem angegebenen voll qualifizierten Namen. Falls sie bisher noch nicht vom Programm benötigt wurde, sucht und lädt der Klassenlader die Klasse. Die Methode liefert niemals null zurück. Falls die Klasse nicht geladen und eingebunden werden konnte, gibt es eine ClassNotFoundException. Eine alternative Methode forName(String name, boolean initialize, ClassLoader loader) ermöglicht auch das Laden mit einem gewünschten Klassenlader. Der Klassenname muss immer voll qualifiziert sein.

ClassNotFoundException und NoClassDefFoundError *

Eine ClassNotFoundException lösen die Methoden

  • forName(…) aus Class und

  • loadClass(String name [, boolean resolve]) aus ClassLoader bzw.

  • findSystemClass(String name) aus ClassLoader

immer dann aus, wenn der Klassenlader die Klasse nach ihrem Klassennamen nicht finden kann. Auslöser ist also die Anwendung, die dynamisch Typen laden will, die dann aber nicht vorhanden sind.

Neben der Exception-Klasse gibt es ein NoClassDefFoundError – ein harter LinkageError, den die JVM immer dann auslöst, wenn sie eine im Bytecode referenzierte Klasse nicht laden kann. Nehmen wir zum Beispiel eine Anweisung wie new MeineKlasse(). Führt die JVM diese Anweisung aus, versucht sie, den Bytecode von MeineKlasse zu laden. Ist der Bytecode für MeineKlasse nach dem Compilieren entfernt worden, löst die JVM durch den nicht geglückten Ladeversuch den NoClassDefFoundError aus. Auch tritt der Fehler auf, wenn beim Laden des Bytecodes die Klasse MeineKlasse zwar gefunden wurde, aber MeineKlasse einen statischen Initialisierungsblock besitzt, der wiederum eine Klasse referenziert, für die keine Klassendatei vorhanden ist.

Während ClassNotFoundException häufiger vorkommt als NoClassDefFoundError, ist die Ausnahme im Allgemeinen ein Indiz dafür, dass ein Java-Archiv im Modulpfad fehlt.

Probleme nach Anwendung eines Obfuscators *

Dass der Compiler automatisch Bytecode gemäß diesem veränderten Quellcode erzeugt, führt nur dann zu unerwarteten Problemen, wenn wir einen Obfuscator über den Programmtext laufen lassen, der nachträglich den Bytecode modifiziert und damit die Bedeutung des Programms bzw. des Bytecodes verschleiert und dabei Typen umbenennt. Offensichtlich darf ein Obfuscator Typen, deren Class-Exemplare abgefragt werden, nicht umbenennen – oder der Obfuscator müsste die entsprechenden Zeichenketten ebenfalls korrekt ersetzen (aber natürlich nicht alle Zeichenketten, die zufällig mit Namen von Klassen übereinstimmen).

 

Zum Seitenanfang

15.3.2    Eine Class ist ein Type Zur vorigen ÜberschriftZur nächsten Überschrift

In Java gibt es unterschiedliche Typen, wobei Klassen, Schnittstellen und Aufzählungstypen von der JVM als Class-Objekte repräsentiert werden. In der Reflection-API repräsentiert die Schnittstelle Type alle Typen. Das ist bisher die implementierende Klasse Class, und dazu kommen einige Unterschnittstellen:

  • ParameterizedType (repräsentiert generische Typen wie List<T>)

  • TypeVariable<D> (repräsentiert beispielsweise T extends Comparable<? super T>)

  • WildcardType (repräsentiert etwa ? super T)

  • GenericArrayType (repräsentiert so etwas wie T[])

Die einzige Methode von Type ist getTypeName(), und das ist sogar »nur« eine Default-Methode, die toString() aufruft.

Type ist die Rückgabe diverser Methoden in der Reflection-API, etwa von getGenericSuperclass() und getGenericInterfaces() der Klasse Class und von vielen weiteren Methoden, die die Javadoc unter »USE« aufzählt.

 


Ihre Meinung?

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java ist auch eine Insel Java ist auch eine Insel

Jetzt Buch bestellen


 Buchempfehlungen
Zum Rheinwerk-Shop: Captain CiaoCiao erobert Java

Captain CiaoCiao erobert Java




Zum Rheinwerk-Shop: Java SE 9 Standard-Bibliothek

Java SE 9 Standard-Bibliothek




Zum Rheinwerk-Shop: Algorithmen in Java

Algorithmen in Java




Zum Rheinwerk-Shop: Objektorientierte Programmierung

Objektorientierte Programmierung




 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und in die Schweiz

InfoInfo



 

 


Copyright © Rheinwerk Verlag GmbH 2021

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



Cookie-Einstellungen ändern