Galileo Computing < openbook > Galileo 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 Mathematisches
6 Eigene Klassen schreiben
7 Angewandte Objektorientierung
8 Exceptions
9 Die Funktionsbibliothek
10 Threads und nebenläufige Programmierung
11 Raum und Zeit
12 Datenstrukturen und Algorithmen
13 Dateien und Datenströme
14 Die eXtensible Markup Language (XML)
15 Grafische Oberflächen mit Swing
16 Grafikprogrammierung
17 Netzwerkprogrammierung
18 Verteilte Programmierung mit RMI und Web-Services
19 JavaServer Pages und Servlets
20 Applets
21 Midlets und die Java ME
22 Datenbankmanagement mit JDBC
23 Reflection und Annotationen
24 Logging und Monitoring
25 Sicherheitskonzepte
26 Java Native Interface (JNI)
27 Dienstprogramme für die Java-Umgebung
A Die Begleit-DVD
Stichwort

Download:
- ZIP, ca. 12,5 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom
Programmieren mit der Java Standard Edition Version 6
Buch: Java ist auch eine Insel

Java ist auch eine Insel
7., aktualisierte Auflage
geb., mit DVD (November 2007)
1.492 S., 49,90 Euro
Galileo Computing
ISBN 978-3-8362-1146-8
Pfeil 3 Klassen und Objekte
Pfeil 3.1 Objektorientierte Programmierung
Pfeil 3.1.1 Warum überhaupt OOP?
Pfeil 3.1.2 Wiederverwertbarkeit
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.4 Neue Objekte erzeugen
Pfeil 3.4.1 Anlegen eines Exemplars einer Klasse mit dem new-Operator
Pfeil 3.4.2 Deklarieren von Referenzvariablen
Pfeil 3.4.3 Zugriff auf Variablen und Methoden mit dem ».«
Pfeil 3.4.4 Konstruktoren nutzen
Pfeil 3.4.5 Die API-Dokumentation
Pfeil 3.5 Import und Pakete
Pfeil 3.6 Mit Referenzen arbeiten
Pfeil 3.6.1 Die null-Referenz
Pfeil 3.6.2 Zuweisungen bei Referenzen
Pfeil 3.6.3 Funktionen mit nicht-primitiven Parametern
Pfeil 3.7 Identität und Gleichheit
Pfeil 3.7.1 Identität von Objekten
Pfeil 3.7.2 Gleichheit und die Methode equals()
Pfeil 3.8 Wrapper-Klassen und Autoboxing
Pfeil 3.8.1 Die Basisklasse Number für numerische Wrapper-Objekte
Pfeil 3.8.2 Die Klasse Integer
Pfeil 3.8.3 Unterschiedliche Ausgabeformate
Pfeil 3.8.4 Autoboxing: Boxing und Unboxing
Pfeil 3.8.5 Die Boolean-Klasse
Pfeil 3.8.6 Die Klassen Double und Float für Fließkommazahlen
Pfeil 3.9 Arrays
Pfeil 3.9.1 Deklaration von Arrays
Pfeil 3.9.2 Arrays mit Inhalt
Pfeil 3.9.3 Die Länge eines Arrays über das Attribut length
Pfeil 3.9.4 Zugriff auf die Elemente über den Index
Pfeil 3.9.5 Array-Objekte erzeugen
Pfeil 3.9.6 Fehler bei Arrays
Pfeil 3.9.7 Vorinitialisierte Arrays
Pfeil 3.9.8 Die erweiterte for-Schleife
Pfeil 3.9.9 Arrays mit nicht-primitiven Elementen
Pfeil 3.9.10 Mehrdimensionale Arrays
Pfeil 3.9.11 Die Wahrheit über die Array-Initialisierung
Pfeil 3.9.12 Mehrere Rückgabewerte
Pfeil 3.9.13 Methode mit variabler Argumentanzahl (Vararg)
Pfeil 3.9.14 Klonen kann sich lohnen – Arrays vermehren
Pfeil 3.9.15 Feldinhalte kopieren
Pfeil 3.9.16 Die Klasse Arrays zum Vergleichen, Füllen und Suchen
Pfeil 3.10 Der Einstiegspunkt für das Laufzeitsystem main()
Pfeil 3.10.1 Kommandozeilen-Argumente verarbeiten
Pfeil 3.10.2 Der Rückgabewert von main() und System.exit()
Pfeil 3.11 Eigene Pakete schnüren
Pfeil 3.11.1 Die package-Anweisung
Pfeil 3.11.2 Importieren von Klassen mit import
Pfeil 3.11.3 Hierarchische Strukturen und das Default-Package
Pfeil 3.11.4 Paketnamen
Pfeil 3.11.5 Klassen mit gleichen Namen in unterschiedlichen Paketen
Pfeil 3.11.6 Statisches Import
Pfeil 3.11.7 Eine Verzeichnisstruktur für eigene Projekte
Pfeil 3.12 Zum Weiterlesen


Galileo Computing - Zum Seitenanfang

3.6 Mit Referenzen arbeiten Zur nächsten ÜberschriftZur vorigen Überschrift


Galileo Computing - Zum Seitenanfang

3.6.1 Die null-Referenz Zur nächsten ÜberschriftZur vorigen Überschrift

In Java gibt es drei spezielle Referenzen: null, this und super. (Wir verschieben this und super auf Kapitel 6.) Das spezielle Literal null lässt sich zur Initialisierung von Referenzvariablen verwenden. Die null-Referenz ist typenlos, kann also jeder Referenzvariable zugewiesen und jeder Funktion übergeben werden, die ein Objekt erwartet. Daher ist Folgendes gültig:

Point  p = null; 
String s = null; 
System.out.println( null );

Da es nur ein null gibt, ist zum Beispiel (Point) null == (String) null. Der Wert ist ausschließlich für Referenzen vorgesehen und kann in keinen primitiven Typ wie die Ganzzahl 0 umgewandelt werden. [Hier unterscheiden sich C(++) und Java. ]

Mit null lässt sich eine ganze Menge machen. Der Haupteinsatz sieht vor, damit uninitialisierte Referenzvariablen zu kennzeichnen, also auszudrücken, dass eine Referenzvariable auf kein Objekt verweist. In Listen oder Bäumen kennzeichnet null aber auch das Fehlen eines gültigen Nachfolgers; null ist dann ein gültiger Indikator und kein Fehlerfall.

Die NullPointerException

Da sich hinter null kein Objekt verbirgt, ist es auch nicht möglich, eine Methode aufzurufen. Der Compiler kennt zwar den Typ jedes Objekts, aber erst die Laufzeitumgebung (JVM) weiß, was referenziert wird. Wird versucht, über die null-Referenz auf eine Eigenschaft eines Objekts zuzugreifen, löst eine JVM eine NullPointerException [Der Name zeigt das Überbleibsel von Zeigern. Zwar haben wir es in Java nicht mit Zeigern zu tun, sondern mit Referenzen, doch heißt es NullPointerException und nicht NullReferenceException. Das erinnert daran, dass eine Referenz ein Objekt identifiziert und eine Referenz auf ein Objekt ein Pointer ist. ] aus.

Listing 3.3 NullPointer.java

/*  1 */import java.awt.Point; 
/*  2 */ 
/*  3 */public class NullPointer 
/*  4 */{ 
/*  5 */  public static void main( String[] args ) 
/*  6 */  { 
/*  7 */    Point  p = null; 
/*  8 */    String s = null; 
/*  9 */ 
/* 10 */    p.setLocation( 1, 2 ); 
/* 11 */    s.length(); 
/* 12 */  } 
/* 13 */}

Wir beobachten eine NullPointerException, denn bei p.setLocation() bricht das Programm mit folgender Ausgabe ab:

java.lang.NullPointerException 
    at NullPointer.main(NullPointer.java:10) 
 Exception in thread "main"

Die Laufzeitumgebung teilt uns in der Fehlermeldung mit, dass sich der Fehler, die NullPointerException, in Zeile 10 befindet.

null-Referenzen testen

Wir wollen an dieser Stelle noch einmal auf die logischen Kurzschlussoperatoren und normalen logischen Operatoren zu sprechen kommen. Letztere werten Operanden nur so lange von links nach rechts aus, bis der Wert der Operation feststeht. Auf den ersten Blick scheint es nicht viel auszumachen, ob alle Teilausdrücke ausgewertet werden oder nicht, in einigen Ausdrücken ist es aber wichtig, wie das folgende Beispiel für die Variable s vom Typ String zeigt:

if ( s != null && s.length() > 0 ) 
  ...

Die Bedingung testet, ob s überhaupt auf ein Objekt verweist und ob die Länge echt größer 0 ist. Diese Schreibweise tritt häufig auf, und der Und-Operator zur Verknüpfung muss ein Kurzschlussoperator sein, da es in diesem Fall ausdrücklich darauf ankommt, dass die Länge nur dann bestimmt wird, wenn die Variable s überhaupt auf ein String-Objekt verweist und nicht null ist. Andernfalls bekämen wir bei s.length() eine NullPointerException, wenn jeder Teilausdruck ausgewertet würde und s gleich null ist.


Galileo Computing - Zum Seitenanfang

3.6.2 Zuweisungen bei Referenzen Zur nächsten ÜberschriftZur vorigen Überschrift

Eine Referenz erlaubt den Zugriff auf das referenzierte Objekt. Es kann durchaus mehrere Kopien dieser Referenz geben, die in Variablen mit unterschiedlichen Namen abgelegt sind – so wie eine Person (ein Personen-Objekt) von den Mitarbeitern als »Chefin« angesprochen wird, aber von ihrem Mann als »Schnuckiputzi«.

Wir wollen uns dies an einem Punkt-Objekt näher ansehen, das wir unter einem alternativen Variablennamen ansprechen können:

Point p = new Point(); 
Point q = p;

Ein Punkt-Objekt wird erzeugt und mit der Variablen p referenziert. Die zweite Zeile speichert nun dieselbe Referenz in der Variablen q. Danach verweisen p und q auf dasselbe Objekt.


Beispiel Beispiel Dies hat zur Konsequenz, dass bei einer Änderung des Punkt-Objekts über die in der Variable p gespeicherte Referenz die Änderung auch bei einem Zugriff über die Variable q beobachtet werden kann.

Point p = new Point(); 
Point q = p; 
p.x = 10; 
System.out.println( q.x );            // 10 
q.y = 5; 
System.out.println( p.y );            // 5

Was wir über die Variable p ändern, kann über die andere Variable q erfragt werden und umgekehrt. Es ist ja das identische Objekt!



Galileo Computing - Zum Seitenanfang

3.6.3 Funktionen mit nicht-primitiven Parametern topZur vorigen Überschrift

Dass sich das gleiche Objekt unter zwei Namen (über zwei verschiedene Variablen) ansprechen lässt, können wir bei Methoden beobachten. Eine Funktion, die im Parameter eine Objektreferenz erhält, bezieht sich genau auf das übergebene Objekt. Das bedeutet: Die Funktion kann dieses Objekt mit den angebotenen Methoden ändern oder auf die Attribute zugreifen.

Listing 3.4 PointFunktion.java

import java.awt.*; 
 
public class InitPoint 
{ 
  static void clear( Point p ) 
  { 
    p.setLocation( 0, 0 ); 
  } 
 
  public static void main( String[] args ) 
  { 
    Point q = new Point( 47, 11 );   // Coordinates (x=47,y=11) 
    clear( q ); 
    System.out.println( q.x );       // 0 
  } 
}

Im dem Moment, in dem main() die Funktion clear() aufruft, gibt es sozusagen die Namen q und p für das Objekt, wobei nur clear() das Objekt unter p kennt und main() nicht, und clear() von dem Namen q keine Idee hat.


Hinweis Hinweis Der Name einer Parametervariable darf durchaus mit dem Namen einer lokalen Variable übereinstimmen, was die Semantik nicht verändert. In unserem Fall hätte clear() die Point-Variable auch q nennen können.


Wertübergabe Call by Value

Primitive Variablen werden immer per Wert kopiert (engl. call by value). Wenn wir folgende Zeilen betrachten, ist leicht zu erkennen, wie sich die Daten verändern. Zunächst deklarieren wir zwei Variablen:

int i = 2; 
int j;

Anschließend weisen wir j den Wert von i zu:

j = i;

An dieser Stelle wird der Wert aus i ausgelesen und in j kopiert. Dabei ist es der Zuweisung ziemlich egal, woher der Wert kommt (er könnte beispielsweise auch die Rückgabe einer Funktion sein). Die Ausgabe gibt demnach 2 aus:

System.out.println( j );    // 2

Ändert sich die Variable i und geben wir j aus, so ist die Ausgabe natürlich immer noch 2, da eine Änderung von j keine Änderung von i nach sich zieht.

i = 3; 
System.out.println( j );    // 2

Referenzübergabe Call by Value

Die Referenzen werden wie primitive Werte kopiert. Daher hat auch die folgende Funktion keine Nebenwirkungen:

static void clear( Point p ) 
{ 
  p = new Point(); 
}

Nach der Zuweisung referenziert die Variable p ein anderes Punkt-Objekt, und das übergebene Argument an die Funktion geht verloren. Diese Änderung wird nach außen hin nicht sichtbar, was bedeutet, dass der Aufrufer kein neues Objekt unter sich hat.

Call by Reference gibt es in Java nicht – ein Blick auf C und C++

In C++ gibt es eine weitere Argumentübergabe, die sich call by reference nennt. Würde eine Funktion wie clear() mit Referenzsemantik deklariert, stellt die Variable p ein Synonym, also einen anderen Namen für eine Variable – in unserem Fall q – dar. Damit würde die Zuweisung im Rumpf den Zeiger auf ein neues Objekt legen. Die swap()-Funktion ist ein gutes Beispiel für die Nützlichkeit von call by reference:

void swap( int& a, int& b ) 
{ 
  int tmp = a; 
  a = b; 
  b = tmp; 
}

Zeiger und Referenzen sind in C++ etwas anderes, was Spracheinsteiger leicht irritiert. Denn in C++ und auch C hätte eine vergleichbare swap()-Funktion auch mit Zeigern implementiert werden können:

void swap( int *a, int *b ) 
{ 
   int tmp = *a; 
   *a = *b; 
   *b = tmp; 
}

Die Implementierung gibt in C(++) einen Verweis auf das Argument.



Ihr Kommentar

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






<< zurück



Copyright © Galileo Press 2008
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.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de