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 Sprachbeschreibung
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Exceptions
7 Generics<T>
8 Äußere.innere Klassen
9 Besondere Klassen der Java SE
10 Architektur, Design und angewandte Objektorientierung
11 Die Klassenbibliothek
12 Bits und Bytes und Mathematisches
13 Datenstrukturen und Algorithmen
14 Threads und nebenläufige Programmierung
15 Raum und Zeit
16 Dateien, Verzeichnisse und Dateizugriffe
17 Datenströme
18 Die eXtensible Markup Language (XML)
19 Grafische Oberflächen mit Swing
20 Grafikprogrammierung
21 Netzwerkprogrammierung
22 Verteilte Programmierung mit RMI
23 JavaServer Pages und Servlets
24 Datenbankmanagement mit JDBC
25 Reflection und Annotationen
26 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Stichwort
Ihre Meinung?

Spacer
 <<   zurück
Java ist auch eine Insel von Christian Ullenboom
Das umfassende Handbuch
Buch: Java ist auch eine Insel

Java ist auch eine Insel
geb., mit DVD
1482 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1506-0
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 zur 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 Variablen und Methoden mit dem ».«
    Pfeil 3.4.5 Konstruktoren nutzen
  Pfeil 3.5 Mit Referenzen arbeiten, Identität und Gleichheit
    Pfeil 3.5.1 Die null-Referenz
    Pfeil 3.5.2 null-Referenzen testen
    Pfeil 3.5.3 Zuweisungen bei Referenzen
    Pfeil 3.5.4 Methoden mit nicht-primitiven Parametern
    Pfeil 3.5.5 Identität von Objekten
    Pfeil 3.5.6 Gleichheit und die Methode »equals()«
  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 Arrays
    Pfeil 3.7.1 Deklaration von Arrays
    Pfeil 3.7.2 Arrays mit Inhalt
    Pfeil 3.7.3 Die Länge eines Arrays über das Attribut length auslesen
    Pfeil 3.7.4 Zugriff auf die Elemente über den Index
    Pfeil 3.7.5 Array-Objekte mit new erzeugen
    Pfeil 3.7.6 Fehler bei Arrays
    Pfeil 3.7.7 Die erweiterte for-Schleife
    Pfeil 3.7.8 Arrays mit nicht-primitiven Elementen
    Pfeil 3.7.9 Mehrdimensionale Arrays *
    Pfeil 3.7.10 Vorinitialisierte Arrays *
    Pfeil 3.7.11 Mehrere Rückgabewerte *
    Pfeil 3.7.12 Methode mit variabler Argumentanzahl (Vararg)
    Pfeil 3.7.13 Klonen kann sich lohnen – Arrays vermehren *
    Pfeil 3.7.14 Feldinhalte kopieren *
    Pfeil 3.7.15 Die Klasse Arrays zum Vergleichen, Füllen und Suchen nutzen
  Pfeil 3.8 Der Einstiegspunkt für das Laufzeitsystem: »main()«
    Pfeil 3.8.1 Kommandozeilenargumente verarbeiten
    Pfeil 3.8.2 Der Rückgabewert von »main()« und »System.exit()«
  Pfeil 3.9 Annotationen
    Pfeil 3.9.1 Annotationstypen @Override, @Deprecated, @SuppressWarnings
  Pfeil 3.10 Zum Weiterlesen


Rheinwerk Computing - Zum Seitenanfang

3.6 Kompilationseinheiten, Imports und Pakete schnüren  Zur nächsten ÜberschriftZur vorigen Ü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 sich zum Beispiel eine Klasse URL und Socket im Paket java.net befinden, denn URLs und Sockets gehören eben zu Netzwerkdingen. 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örten, aber dazu mehr in Abschnitt 11.1.1, »Übersicht über die Pakete der Standardbibliothek«.


Rheinwerk Computing - Zum Seitenanfang

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

Um die Klasse Point, die im Paket java.awt liegt, außerhalb des Pakets java.awt zu nutzen, 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.2  Programm ohne und mit import-Deklaration

Listing 3.4  AwtWithoutImport.java



class AwtWithoutImport
{
 public static void main( String[] args )
 {
  java.awt.Point p = new java.awt.Point();
  java.awt.Polygon poly = new java.awt.Polygon();
  poly.addPoint( 10, 10 );
  poly.addPoint( 10, 20 );
  poly.addPoint( 20, 10 );

  System.out.println( p );
  System.out.println( poly.contains(15, 15) );
 }
}

Listing 3.5  AwtWithImport.java

import java.awt.Point;
import java.awt.Polygon;

class AwtWithImport
{
 public static void main( String[] args )
 {
  Point p = new Point();
  Polygon poly = new Polygon();
  poly.addPoint( 10, 10 );
  poly.addPoint( 10, 20 );
  poly.addPoint( 20, 10 );

  System.out.println( p );
  System.out.println( poly.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 erreichen  Zur 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 sind das 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 Pakete  Zur 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 auch 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 [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 Klasse an:

com/tutego/ com/tutego/Chocolate.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-Deklaration  Zur nächsten ÜberschriftZur vorigen Überschrift

Um die Klasse Chocolate 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):

package com.tutego;

public class Chocolate
{
 ...
}

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 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: Die Konflikte währen vorprogrammiert.

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

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

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.6  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. Doch dazu später mehr.


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 *  topZur 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
 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.


Nutzungsbestimmungen | Datenschutz | Impressum

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