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 3 Klassen und Objekte
Pfeil 3.1 Objektorientierte Programmierung (OOP)
Pfeil 3.1.1 Warum überhaupt OOP?
Pfeil 3.1.2 Denk ich an Java, denk ich an Wiederverwendbarkeit
Pfeil 3.2 Eigenschaften einer Klasse
Pfeil 3.2.1 Klassenarbeit mit Point
Pfeil 3.3 Natürlich modellieren mit der UML (Unified Modeling Language) *
Pfeil 3.3.1 Hintergrund und Geschichte der UML
Pfeil 3.3.2 Wichtige Diagrammtypen der UML
Pfeil 3.3.3 UML-Werkzeuge
Pfeil 3.4 Neue Objekte erzeugen
Pfeil 3.4.1 Ein Exemplar einer Klasse mit dem Schlüsselwort new anlegen
Pfeil 3.4.2 Der Zusammenhang von new, Heap und Garbage-Collector
Pfeil 3.4.3 Deklarieren von Referenzvariablen
Pfeil 3.4.4 Jetzt mach mal ’nen Punkt: Zugriff auf Objektattribute und -methoden
Pfeil 3.4.5 Überblick über Point-Methoden
Pfeil 3.4.6 Konstruktoren nutzen
Pfeil 3.5 ZZZZZnake
Pfeil 3.6 Pakete schnüren, Imports und Kompilationseinheiten
Pfeil 3.6.1 Java-Pakete
Pfeil 3.6.2 Pakete der Standardbibliothek
Pfeil 3.6.3 Volle Qualifizierung und import-Deklaration
Pfeil 3.6.4 Mit import p1.p2.* alle Typen eines Pakets erreichen
Pfeil 3.6.5 Hierarchische Strukturen über Pakete
Pfeil 3.6.6 Die package-Deklaration
Pfeil 3.6.7 Unbenanntes Paket (default package)
Pfeil 3.6.8 Klassen mit gleichen Namen in unterschiedlichen Paketen *
Pfeil 3.6.9 Kompilationseinheit (Compilation Unit)
Pfeil 3.6.10 Statischer Import *
Pfeil 3.7 Mit Referenzen arbeiten, Identität und Gleichheit (Gleichwertigkeit)
Pfeil 3.7.1 null-Referenz und die Frage der Philosophie
Pfeil 3.7.2 Alles auf null? Referenzen testen
Pfeil 3.7.3 Zuweisungen bei Referenzen
Pfeil 3.7.4 Methoden mit Referenztypen als Parametern
Pfeil 3.7.5 Identität von Objekten
Pfeil 3.7.6 Gleichheit (Gleichwertigkeit) und die Methode equals(…)
Pfeil 3.8 Arrays
Pfeil 3.8.1 Grundbestandteile
Pfeil 3.8.2 Deklaration von Arrays
Pfeil 3.8.3 Arrays mit Inhalt
Pfeil 3.8.4 Die Länge eines Arrays über das Attribut length auslesen
Pfeil 3.8.5 Zugriff auf die Elemente über den Index
Pfeil 3.8.6 Array-Objekte mit new erzeugen
Pfeil 3.8.7 Typische Array-Fehler
Pfeil 3.8.8 Arrays als Methodenparameter
Pfeil 3.8.9 Vorinitialisierte Arrays
Pfeil 3.8.10 Die erweiterte for-Schleife
Pfeil 3.8.11 Arrays mit nichtprimitiven Elementen
Pfeil 3.8.12 Methode mit variabler Argumentanzahl (Vararg)
Pfeil 3.8.13 Mehrdimensionale Arrays *
Pfeil 3.8.14 Nichtrechteckige Arrays *
Pfeil 3.8.15 Die Wahrheit über die Array-Initialisierung *
Pfeil 3.8.16 Mehrere Rückgabewerte *
Pfeil 3.8.17 Klonen kann sich lohnen – Arrays vermehren *
Pfeil 3.8.18 Array-Inhalte kopieren *
Pfeil 3.8.19 Die Klasse Arrays zum Vergleichen, Füllen, Suchen, Sortieren nutzen
Pfeil 3.8.20 Eine lange Schlange
Pfeil 3.9 Der Einstiegspunkt für das Laufzeitsystem: main(…)
Pfeil 3.9.1 Korrekte Deklaration der Startmethode
Pfeil 3.9.2 Kommandozeilenargumente verarbeiten
Pfeil 3.9.3 Der Rückgabetyp von main(…) und System.exit(int) *
Pfeil 3.10 Grundlagen von Annotationen und Generics
Pfeil 3.10.1 Generics
Pfeil 3.10.2 Annotationen
Pfeil 3.10.3 Annotationstypen aus java.lang
Pfeil 3.10.4 @Deprecated
Pfeil 3.10.5 @SuppressWarnings
Pfeil 3.11 Zum Weiterlesen
 

Zum Seitenanfang

3.6Pakete schnüren, Imports und Kompilationseinheiten Zur vorigen ÜberschriftZur nächsten Überschrift

Die Klassenbibliothek von Java ist mit Tausenden Typen sehr umfangreich und deckt alles ab, was Entwickler von plattformunabhängigen Programmen als Basis benötigen. Dazu gehören Datenstrukturen, Klassen zur Datums-/Zeitberechnung, Dateiverarbeitung usw. Die meisten Typen sind in Java selbst implementiert (und der Quellcode in der Regel aus der Entwicklungsumgebung direkt verfügbar), einige Teile sind nativ implementiert, etwa wenn es darum geht, aus einer Datei zu lesen.

Wenn wir eigene Klassen programmieren, ergänzen diese sozusagen die Standardbibliothek; im Endeffekt wächst damit die Anzahl der möglichen Typen, die ein Programm nutzen kann.

 

Zum Seitenanfang

3.6.1Java-Pakete Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Paket ist eine Gruppe thematisch zusammengehöriger Typen. Pakete könnten Unterpakete besitzen, die in der Angabe durch einen Punkt getrennt werden. Die Gruppierung lässt sich sehr gut an der Java-Bibliothek beobachten, wo zum Beispiel eine Klasse File und RandomAccessFile dem Paket java.io angehören, denn Dateien und Möglichkeiten zum wahlfreien Zugriff auf Dateien gehören eben zur Ein-/Ausgabe. Ein Punkt und ein Polygon, repräsentiert durch die Klassen Point und Polygon, gehören in das Paket für grafische Oberflächen, und das ist das Paket java.awt.

 

Zum Seitenanfang

3.6.2Pakete der Standardbibliothek Zur vorigen ÜberschriftZur nächsten Überschrift

Die Klassen der Standardbibliothek sitzen in Paketen, die mit java und javax beginnen. So befindet sich java.awt.Point in einem Paket der Standardbibliothek, was durch den Teil java zu erkennen ist. Wenn jemand eigene Klassen in Pakete mit dem Präfix java setzen würde, etwa java.ui, würde er damit Verwirrung stiften, da nicht mehr nachvollziehbar ist, ob das Paket Bestandteil jeder Distribution ist. Klassen, die mit javax beginnen, müssen nicht zwingend zur Java SE gehören, aber dazu folgt mehr in Abschnitt 14.1.1, »Übersicht über die Pakete der Standardbibliothek«.

 

Zum Seitenanfang

3.6.3Volle Qualifizierung und import-Deklaration Zur vorigen ÜberschriftZur nächsten Überschrift

Um die Klasse Point, die im Paket java.awt liegt, außerhalb des Pakets java.awt zu nutzen – und das ist für uns Nutzer immer der Fall –, muss sie dem Compiler mit der gesamten Paketangabe bekannt gemacht werden. Hierzu reicht der Klassenname allein nicht aus, denn es kann ja sein, dass der Klassenname mehrdeutig ist und eine Klassendeklaration in unterschiedlichen Paketen existiert. (In der Java-Bibliothek gibt es dazu einige Beispiele, etwa java.util.Date und java.sql.Date.)

Um dem Compiler die präzise Zuordnung einer Klasse zu einem Paket zu ermöglichen, gibt es zwei Möglichkeiten: Zum einen lassen sich die Typen voll qualifizieren, wie wir das bisher getan haben. Eine alternative und praktischere Möglichkeit besteht darin, den Compiler mit einer import-Deklaration auf die Typen im Paket aufmerksam zu machen:

AwtWithoutImport.java







class AwtWithoutImport {

public static void main( String[] args )

{

java.awt.Point p = new java.awt.Point();



java.awt.Polygon t = new java.awt.Polygon();

t.addPoint( 10, 10 );

t.addPoint( 10, 20 );

t.addPoint( 20, 10 );



System.out.println( p );

System.out.println( t.contains(15, 15) );

}

}

AwtWithImport.java

import java.awt.Point;

import java.awt.Polygon;



class AwtWithImport {

public static void main( String[] args )

{

Point p = new Point();





Polygon t = new Polygon();



t.addPoint( 10, 10 );

t.addPoint( 10, 20 );

t.addPoint( 20, 10 );



System.out.println( p );

System.out.println( t.contains(15, 15) );

}

}

Tabelle 3.3Programm ohne und mit import-Deklaration

Während der Quellcode auf der linken Seite die volle Qualifizierung verwendet und jeder Verweis auf einen Typ mehr Schreibarbeit kostet, ist im rechten Fall beim import nur der Klassenname genannt und die Paketangabe in ein import »ausgelagert«. Kommt der Compiler zu einer Anweisung wie Point p = new Point();, findet er die Deklaration einer Klasse Point im Paket java.awt und kennt damit die für ihn unabkömmliche absolute Qualifizierung.

[»]Hinweis

Die Typen aus java.lang sind automatisch importiert, sodass z. B. ein import java.lang. String; nicht nötig ist.

 

Zum Seitenanfang

3.6.4Mit import p1.p2.* alle Typen eines Pakets erreichen Zur vorigen ÜberschriftZur nächsten Überschrift

Greift eine Java-Klasse auf mehrere andere Typen des gleichen Pakets zurück, kann die Anzahl der import-Deklarationen groß werden. In unserem Beispiel nutzen wir mit Point und Polygon nur zwei Klassen aus java.awt, aber es lässt sich schnell ausmalen, was passiert, wenn aus dem Paket für grafische Oberflächen zusätzlich Fenster, Beschriftungen, Schaltflächen, Schieberegler usw. eingebunden werden. Die Lösung in diesem Fall ist ein *, das das letzte Glied in einer import-Deklaration sein darf:

import java.awt.*;

import java.io.*;

Mit dieser Syntax kennt der Compiler alle Typen im Paket java.awt und java.io, sodass eine Klasse Point und Polygon genau bekannt ist, wie auch die Klasse File.

[»]Hinweis

Das * ist nur in der letzten Hierarchie erlaubt und gilt immer für alle Typen in diesem Paket. Syntaktisch falsch sind:

import *; // inline Syntax error on token "*", Identifier expected

import java.awt.Po*; // inline Syntax error on token "*", delete this token

Eine Anweisung wie import java.*; ist zwar syntaktisch korrekt, aber dennoch ohne Wirkung, denn direkt im Paket java gibt es keine Typdeklarationen, sondern nur Unterpakete.

Die import-Deklaration bezieht sich nur auf ein Verzeichnis (in der Annahme, dass die Pakete auf das Dateisystem abgebildet werden) und schließt die Unterverzeichnisse nicht ein.

Das * verkürzt zwar die Anzahl der individuellen import-Deklarationen, es ist aber gut, zwei Dinge im Kopf zu behalten:

  • Falls zwei unterschiedliche Pakete einen gleichlautenden Typ beherbergen, etwa Date in java.util und java.sql, so kommt es bei der Verwendung des Typs zu einem Übersetzungsfehler. Hier muss voll qualifiziert werden.

  • Die Anzahl der import-Deklarationen sagt etwas über den Grad der Komplexität aus. Je mehr import-Deklarationen es gibt, desto größer werden die Abhängigkeiten zu anderen Klassen, was im Allgemeinen ein Alarmzeichen ist. Zwar zeigen grafische Tools die Abhängigkeiten genau an, doch ein import * kann diese erst einmal verstecken.

 

Zum Seitenanfang

3.6.5Hierarchische Strukturen über Pakete Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Java-Paket ist eine logische Gruppierung von Klassen. Pakete lassen sich in Hierarchien ordnen, sodass in einem Paket wieder ein anderes Paket liegen kann; das ist genauso wie bei der Verzeichnisstruktur des Dateisystems. In der Standardbibliothek ist das Paket java ein Hauptzweig, aber das gilt auch für javax. Unter dem Paket java liegen dann zum Beispiel die Pakete awt und util, und unter javax liegen dann swing und sonstige Unterpakete.

Die zu einem Paket gehörenden Klassen befinden sich normalerweise[ 113 ](Ich schreibe »normalerweise«, da die Paketstruktur nicht zwingend auf Verzeichnisse abgebildet werden muss. Pakete könnten beispielsweise vom Klassenlader aus einer Datenbank gelesen werden. Im Folgenden wollen wir aber immer von Verzeichnissen ausgehen. ) im gleichen Verzeichnis. Der Name des Pakets ist dann gleich dem Namen des Verzeichnisses (und natürlich umgekehrt). Statt des Verzeichnistrenners (etwa »/« oder »\«) steht ein Punkt.

Nehmen wir folgende Verzeichnisstruktur mit einer Hilfsklasse an:

com/tutego/

com/tutego/DatePrinter.class

Hier ist der Paketname com.tutego und somit der Verzeichnisname com/tutego/. Umlaute und Sonderzeichen sollten vermieden werden, da sie auf dem Dateisystem immer wieder für Ärger sorgen. Aber Bezeichner sollten ja sowieso immer auf Englisch sein.

Der Aufbau von Paketnamen

Prinzipiell kann ein Paketname beliebig sein, doch Hierarchien bestehen in der Regel aus umgedrehten Domänennamen. Aus der Domäne zur Webseite http://tutego.com wird also com.tutego. Diese Namensgebung gewährleistet, dass Klassen auch weltweit eindeutig bleiben. Ein Paketname wird in aller Regel komplett kleingeschrieben.

 

Zum Seitenanfang

3.6.6Die package-Deklaration Zur vorigen ÜberschriftZur nächsten Überschrift

Um die Klasse DatePrinter in ein Paket com.tutego zu setzen, müssen zwei Dinge gelten:

  • Sie muss sich physikalisch in einem Verzeichnis befinden, also in com/tutego/.

  • Der Quellcode enthält zuoberst eine package-Deklaration.

Die package-Deklaration muss ganz am Anfang stehen, sonst gibt es einen Übersetzungsfehler (selbstverständlich lassen sich Kommentare vor die package-Deklaration setzen):

Listing 3.6com/tutego/DatePrinter.java

package com.tutego;



import java.util.Date;



public class DatePrinter {

public static void printCurrentDate() {

System.out.printf( "%tD%n", new Date() );

}

}

Hinter die package-Deklaration kommen wie gewohnt import-Anweisungen und die Typdeklarationen.

Um die Klasse zu nutzen, bieten sich wie bekannt zwei Möglichkeiten: einmal über die volle Qualifizierung und einmal über die import-Deklaration. Die erste Variante:

Listing 3.7DatePrinterUser1.java

public class DatePrinterUser1 {

public static void main( String[] args ) {

com.tutego.DatePrinter.printCurrentDate(); // 05/31/11

}

}

Und die Variante mit der import-Deklaration:

Listing 3.8DatePrinterUser2.java

import com.tutego.DatePrinter;



public class DatePrinterUser2 {

public static void main( String[] args ) {

DatePrinter.printCurrentDate(); // 05/31/11

}

}
 

Zum Seitenanfang

3.6.7Unbenanntes Paket (default package) Zur vorigen ÜberschriftZur nächsten Überschrift

Eine Klasse ohne Paket-Angabe befindet sich im unbenannten Paket (engl. unnamed package) bzw. Default-Paket. Es ist eine gute Idee, eigene Klassen immer in Paketen zu organisieren. Das erlaubt auch feinere Sichtbarkeiten, und Konflikte mit anderen Unternehmen und Autoren werden vermieden. Es wäre ein großes Problem, wenn a) jedes Unternehmen unübersichtlich alle Klassen in das unbenannte Paket setzt und dann b) versucht, die Bibliotheken auszutauschen: Konflikte wären vorprogrammiert.

Das Verzeichnis »default package« steht in Eclipse für das unbenannte Paket.

Abbildung 3.7Das Verzeichnis »default package« steht in Eclipse für das unbenannte Paket.

Eine im Paket befindliche Klasse kann jede andere sichtbare Klasse aus anderen Paketen importieren, aber keine Klassen aus dem unbenannten Paket. Nehmen wir Sugar im unbenannten Paket und Chocolate im Paket com.tutego an:

Sugar.class

com/tutego/Chocolate.class

Die Klasse Chocolate kann Sugar nicht nutzen, da Klassen aus dem unbenannten Paket nicht für Unterpakete sichtbar sind. Nur andere Klassen im unbenannten Paket können Klassen im unbenannten Paket nutzen.

Stände nun Sugar in einem Paket – das auch ein Oberpaket sein kann! –, so wäre das wiederum möglich, und Chocolate könnte Sugar importieren.

com/Sugar.class

com/tutego/Chocolate.class

 

Zum Seitenanfang

3.6.8Klassen mit gleichen Namen in unterschiedlichen Paketen * Zur vorigen ÜberschriftZur nächsten Überschrift

Ein Problem gibt es bei mehreren gleich benannten Klassen in unterschiedlichen Paketen. Hier ist eine volle Qualifizierung nötig. So gibt es in den Paketen java.awt und java.util eine Liste. Ein einfaches import java.awt.* und java.util.* hilft da nicht, weil der Compiler nicht weiß, ob die GUI-Komponente oder die Datenstruktur gemeint ist. Auch sagt ein import nichts darüber aus, ob die Klassen in der importierenden Datei jemals gebraucht werden. Das Gleiche gilt für die Klasse Date, die einmal in java.util und einmal in java.sql zu finden ist. Lustigerweise erweitert java.sql.Date die Klasse java.util.Date. Dass der Compiler hier nicht durcheinanderkommt, ist ganz einfach dadurch zu erklären, dass er die Klassen nicht nur anhand ihres Namens unterscheidet, sondern vielmehr auch anhand ihrer Pakete. Der Compiler betrachtet intern immer eine volle Qualifizierung.

 

Zum Seitenanfang

3.6.9Kompilationseinheit (Compilation Unit) Zur vorigen ÜberschriftZur nächsten Überschrift

Die package- und import-Deklarationen gehören nicht wirklich zu der Typdeklaration, die nur ein class C { } oder verwandte Typdeklarationen umfasst. Genau genommen sind dies alles Bestandteile einer Kompilationseinheit (Compilation Unit). So besteht eine Kompilationseinheit aus höchstens einer Paketdeklaration, beliebig vielen import-Deklarationen und beliebig vielen Typdeklarationen. Ein Paket ist letztendlich eine Sammlung aus Kompilationseinheiten.

 

Zum Seitenanfang

3.6.10Statischer Import * Zur vorigen ÜberschriftZur nächsten Überschrift

Das import informiert den Compiler über die Pakete, sodass ein Typ nicht mehr voll qualifiziert werden muss, wenn er im import-Teil explizit aufgeführt wird oder wenn das Paket des Typs genannt ist.

Falls eine Klasse statische Methoden oder Konstanten vorschreibt, werden ihre Eigenschaften immer über den Typnamen angesprochen. Es gibt nun mit dem statischen Import die Möglichkeit, die statischen Methoden oder Variablen ohne Typnamen sofort zu nutzen.

Praktisch ist das zum Beispiel für die Bildschirmausgabe, wenn die statische Variable out aus System eingebunden wird:

import static java.lang.System.out;

Bei der sonst üblichen Ausgabe über System.out.printXXX(…) kann nach dem statischen Import der Klassenname entfallen, und es bleibt beim out.printXXX(…):

Listing 3.9StaticImport.java

import static java.lang.System.out;

import static javax.swing.JOptionPane.showInputDialog;

import static java.lang.Integer.parseInt;

import static java.lang.Math.max;

import static java.lang.Math.min;



class StaticImport {



public static void main( String[] args ) {

int i = parseInt( showInputDialog( "Erste Zahl" ) );

int j = parseInt( showInputDialog( "Zweite Zahl" ) );

out.printf( "%d ist größer oder gleich %d.%n",

max(i, j), min(i, j) );

}

}

Mehrere Typen statisch importieren

Der statische Import

import static java.lang.Math.max;

import static java.lang.Math.min;

bindet die statische max(…)/min(…)-Methode ein. Besteht Bedarf an weiteren statischen Methoden, gibt es neben der individuellen Aufzählung eine Wildcard-Variante:

import static java.lang.Math.*;

Best Practice

Auch wenn Java diese Möglichkeit bietet, sollte der Einsatz maßvoll erfolgen. Die Möglichkeit der statischen Importe ist nützlich, wenn Klassen Konstanten nutzen wollen, allerdings besteht auch die Gefahr, dass durch den fehlenden Typnamen nicht mehr sichtbar ist, woher die Eigenschaft eigentlich kommt und welche Abhängigkeit sich damit aufbaut. Auch gibt es Probleme mit gleichlautenden Methoden: Eine Methode aus der eigenen Klasse überdeckt statische importierte Methoden.

 


Ihr Kommentar

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

>> Zum Feedback-Formular
<< zurück

 

 


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