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 Exceptions
7 Äußere.innere Klassen
8 Besondere Klassen der Java SE
9 Generics<T>
10 Architektur, Design und angewandte Objektorientierung
11 Die Klassenbibliothek
12 Einführung in die nebenläufige Programmierung
13 Einführung in Datenstrukturen und Algorithmen
14 Einführung in grafische Oberflächen
15 Einführung in Dateien und Datenströme
16 Einführung in die <XML>-Verarbeitung mit Java
17 Einführung ins Datenbankmanagement mit JDBC
18 Bits und Bytes und Mathematisches
19 Die Werkzeuge des JDK
A Die Klassenbibliothek
Stichwort

Download:
- Aufgaben, ca. 1,1 MB
- Programme, ca. 12,8 MB

Buch bestellen
Ihre Meinung?

Spacer
Java ist auch eine Insel von Christian Ullenboom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
Galileo Computing
1308 S., 10., aktualisierte Auflage, geb., mit DVD
ca. 49,90 Euro, ISBN 978-3-8362-1802-3
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 Die Klasse Point
Pfeil 3.3 Die 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 new-Operator anlegen
Pfeil 3.4.2 Garbage-Collector (GC) – Es ist dann mal weg
Pfeil 3.4.3 Deklarieren von Referenzvariablen
Pfeil 3.4.4 Zugriff auf Objektattribute und -methoden mit dem ».«
Pfeil 3.4.5 Überblick über Point-Methoden
Pfeil 3.4.6 Konstruktoren nutzen
Pfeil 3.5 ZZZZZnake
Pfeil 3.6 Kompilationseinheiten, Imports und Pakete schnüren
Pfeil 3.6.1 Volle Qualifizierung und import-Deklaration
Pfeil 3.6.2 Mit import p1.p2.* alle Typen eines Pakets erreichen
Pfeil 3.6.3 Hierarchische Strukturen über Pakete
Pfeil 3.6.4 Die package-Deklaration
Pfeil 3.6.5 Unbenanntes Paket (default package)
Pfeil 3.6.6 Klassen mit gleichen Namen in unterschiedlichen Paketen *
Pfeil 3.6.7 Compilationseinheit (Compilation Unit)
Pfeil 3.6.8 Statischer Import *
Pfeil 3.6.9 Eine Verzeichnisstruktur für eigene Projekte *
Pfeil 3.7 Mit Referenzen arbeiten, Identität und Gleichheit
Pfeil 3.7.1 Die null-Referenz
Pfeil 3.7.2 null-Referenzen testen
Pfeil 3.7.3 Zuweisungen bei Referenzen
Pfeil 3.7.4 Methoden mit nicht-primitiven Parametern
Pfeil 3.7.5 Identität von Objekten
Pfeil 3.7.6 Gleichheit 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 Feldfehler
Pfeil 3.8.8 Feld-Objekte als Parametertyp
Pfeil 3.8.9 Vorinitialisierte Arrays
Pfeil 3.8.10 Die erweiterte for-Schleife
Pfeil 3.8.11 Arrays mit nicht-primitiven Elementen
Pfeil 3.8.12 Mehrdimensionale Arrays *
Pfeil 3.8.13 Nichtrechteckige Arrays *
Pfeil 3.8.14 Die Wahrheit über die Array-Initialisierung *
Pfeil 3.8.15 Mehrere Rückgabewerte *
Pfeil 3.8.16 Methode mit variabler Argumentanzahl (Vararg)
Pfeil 3.8.17 Klonen kann sich lohnen – Arrays vermehren *
Pfeil 3.8.18 Feldinhalte 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() *
Pfeil 3.10 Annotationen und Generics
Pfeil 3.10.1 Generics
Pfeil 3.10.2 Annotationen
Pfeil 3.10.3 Eigene Metadaten setzen
Pfeil 3.10.4 Annotationstypen @Override, @Deprecated, @SuppressWarnings
Pfeil 3.11 Zum Weiterlesen

Rheinwerk Computing - Zum Seitenanfang

3.6 Kompilationseinheiten, Imports und Pakete schnürenZur 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.

Die Paketnamen java, javax

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 11.1.1, »Übersicht über die Pakete der Standardbibliothek«.


Rheinwerk Computing - Zum Seitenanfang

3.6.1 Volle Qualifizierung und import-DeklarationZur nächsten ÜberschriftZur vorigen Ü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:

Tabelle 3.3: Programm ohne und mit import-Deklaration

Listing 3.6: 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) );
}
}

Listing 3.7: 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) );
}
}

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 zum Beispiel ein import java.lang.String; nicht nötig ist.


Rheinwerk Computing - Zum Seitenanfang

3.6.2 Mit import p1.p2.* alle Typen eines Pakets erreichenZur nächsten ÜberschriftZur vorigen Ü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 und so weiter 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 *;            // Fehler Syntax error on token "*", Identifier expected
import java.awt.Po*; // Fehler 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 Typendeklarationen, 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 mit 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.

Rheinwerk Computing - Zum Seitenanfang

3.6.3 Hierarchische Strukturen über PaketeZur nächsten ÜberschriftZur vorigen Ü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[99](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.


Rheinwerk Computing - Zum Seitenanfang

3.6.4 Die package-DeklarationZur nächsten ÜberschriftZur vorigen Ü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.8: com/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.9: DatePrinterUser1.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.10: DatePrinterUser2.java

import com.tutego.DatePrinter;

public class DatePrinterUser2
{
public static void main( String[] args )
{
DatePrinter.printCurrentDate(); // 05/31/11
}
}

Rheinwerk Computing - Zum Seitenanfang

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

Falls eine Klasse ohne Paket-Angabe implementiert wird, befindet sie sich standardmäßig im unbenannten Paket (engl. unnamed package) oder 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.

Abbildung
Abbildung

Abbildung 3.7: Das 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 Chocolate im Paket com.tutego und Sugar im unbenannten Paket 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 – was 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


Rheinwerk Computing - Zum Seitenanfang

3.6.6 Klassen mit gleichen Namen in unterschiedlichen Paketen *Zur nächsten ÜberschriftZur vorigen Ü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.


Rheinwerk Computing - Zum Seitenanfang

3.6.7 Compilationseinheit (Compilation Unit)Zur nächsten ÜberschriftZur vorigen Ü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 Compilationseinheit (Compilation Unit). So besteht eine Compilationseinheit aus höchstens einer Paketdeklaration, beliebig vielen import-Deklarationen und beliebig vielen Typdeklarationen. Ein Paket ist letztendlich eine Sammlung aus Compilationseinheiten.


Rheinwerk Computing - Zum Seitenanfang

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

Das import hat in Java die Bedeutung, den Compiler über die Pakete zu informieren, sodass eine Klasse nicht mehr voll qualifiziert werden muss, wenn sie im import-Teil explizit aufgeführt wird oder wenn das Paket der Klasse genannt ist.

Falls eine Klasse statische Methoden oder Konstanten vorschreibt, werden ihre Eigenschaften immer über den Klassennamen angesprochen. Es gibt nun mit dem statischen Import die Möglichkeit, die Klasseneigenschaften wie eigene statische Methoden oder Variablen ohne Klassennamen 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.11: StaticImport.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.*;

Auch wenn Java seit Version 5 diese Möglichkeit bietet, sollte der Einsatz maßvoll erfolgen. Die Möglichkeit der statischen Importe wird dann nützlicher, wenn Klassen Konstanten nutzen wollen.

Hinweis

Eine Objektmethode aus der eigenen Klasse überdeckt statische importierte Methoden, was im Fall der toString()-Methode auffällt, die statisch aus der Utility-Klasse Arrays eingebunden werden kann. Der Compiler interpretiert toString() als Aufruf einer Objektmethode (auch dann, wenn die aufrufende Methode selbst statisch ist).


Rheinwerk Computing - Zum Seitenanfang

3.6.9 Eine Verzeichnisstruktur für eigene Projekte *Zur vorigen Überschrift

Neben der Einteilung in Pakete für das eigene Programm ist es auch sinnvoll, die gesamte Applikation in verschiedenen Verzeichnissen aufzubauen. Im Allgemeinen finden sich drei wichtige Hauptverzeichnisse: src für die Quellen, lib für externe Bibliotheken, auf die das Programm aufbaut, und bin (oder build) für die erzeugten Klassen-Dateien. Das Verzeichnis src lässt sich noch weiter unterteilen, etwa für Quellen, die Testfälle implementieren, oder für Beispiele:

src/
core/
examples/
test/
lib/
bin/

Mehr Anregungen zur Verzeichnisstruktur gibt die Webseite http://java.sun.com/blueprints/code/projectconventions.html.



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 Bibliotheken






 Java SE Bibliotheken


Zum Katalog: Professionell entwickeln mit Java EE 7






 Professionell
 entwickeln mit
 Java EE 7


Zum Katalog: Einstieg in Eclipse






 Einstieg in
 Eclipse


Zum Katalog: Einstieg in Java






 Einstieg in
 Java


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2011
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