Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage |
<< | < | > | >> | API | Kapitel 5 - Datentypen |
Java kennt acht elementare Datentypen, die gemäß Sprachspezifikation als primitive Datentypen bezeichnet werden. Daneben gibt es die Möglichkeit, Arrays zu definieren (die eingeschränkte Objekttypen sind), und als objektorientierte Sprache erlaubt Java natürlich die Definition von Objekttypen.
Im Gegensatz zu C und C++ gibt es die folgenden Elemente in Java jedoch nicht:
|
|
Was auf den ersten Blick wie eine Designschwäche aussieht, entpuppt sich bei näherem Hinsehen als Stärke von Java. Der konsequente Verzicht auf zusätzliche Datentypen macht die Sprache leicht erlernbar und verständlich. Die Vergangenheit hat mehrfach gezeigt, dass Programmiersprachen mit einem überladenen Typkonzept (zum Beispiel PL/I oder ADA) auf Dauer keine Akzeptanz finden.
Tatsächlich ist es ohne Weiteres möglich, die unverzichtbaren Datentypen mit den in Java eingebauten Hilfsmitteln nachzubilden. So lassen sich beispielsweise Zeiger zur Konstruktion dynamischer Datenstrukturen mit Hilfe von Referenzvariablen simulieren und Recordtypen sind nichts anderes als Klassen ohne Methoden. Der Verzicht auf Low-Level-Datenstrukturen, wie beispielsweise Zeiger zur Manipulation von Speicherstellen oder Bitfelder zur Repräsentation von Hardware-Elementen, ist dagegen gewollt.
Alle primitiven Datentypen in Java haben - unabhängig von der Plattform auf der Java ausgeführt wird - eine feste Länge, die von den Designern der Sprache ein für allemal verbindlich festgelegt wurde. Ein sizeof-Operator, wie er in C vorhanden ist, wird in Java daher nicht benötigt und ist auch nicht vorhanden.
Ein weiterer Unterschied zu C und den meisten anderen Programmiersprachen besteht darin, dass Variablen in Java immer einen definierten Wert haben. Bei Membervariablen (also Variablen innerhalb von Klassen, siehe Kapitel 8) bekommt eine Variable einen Standardwert zugewiesen, wenn dieser nicht durch eine explizite Initialisierung geändert wird. Bei lokalen Variablen sorgt der Compiler durch eine Datenflussanalyse dafür, dass diese vor ihrer Verwendung explizit initialisiert werden. Eine Erläuterung dieses Konzepts, das unter dem Namen Definite Assignment in der Sprachdefinition beschrieben wird, ist Bestandteil von Kapitel 6. Tabelle 5.1 listet die in Java verfügbaren Basistypen und ihre Standardwerte auf:
Typname | Länge | Wertebereich | Standardwert |
boolean | 1 | true, false | false |
char | 2 | Alle Unicode-Zeichen | \u0000 |
byte | 1 | -27...27-1 | 0 |
short | 2 | -215...215-1 | 0 |
int | 4 | -231...231-1 | 0 |
long | 8 | -263...263-1 | 0 |
float | 4 | +/-3.40282347 * 1038 | 0.0 |
double | 8 | +/-1.79769313486231570 * 10308 | 0.0 |
Tabelle 5.1: Primitive Datentypen
Mit boolean besitzt Java einen eigenen logischen Datentyp und beseitigt damit eine oft diskutierte Schwäche von C und C++. Der boolean-Typ muss zwangsweise dort verwendet werden, wo ein logischer Operand erforderlich ist. Ganzzahlige Typen mit den Werten 0 oder 1 dürfen nicht als Ersatz für einen logischen Typ verwendet werden.
Der Datentyp boolean kennt zwei verschiedene Werte, nämlich true und false. Neben den vordefinierten Konstanten gibt es keine weiteren Literale für logische Datentypen.
Java wurde mit dem Anspruch entworfen, bekannte Schwächen bestehender Programmiersprachen zu vermeiden, und der Wunsch nach Portabilität stand ganz oben auf der Liste der Designziele. Konsequenterweise wurde der Typ char in Java daher bereits von Anfang an 2 Byte groß gemacht und speichert seine Zeichen auf der Basis des Unicode-Zeichensatzes. Als einziger integraler Datentyp ist char nicht vorzeichenbehaftet.
Da das Sprachdesign und das Java-API so gestaltet wurden, dass die Verwendung des Unicode-Zeichensatzes weitgehend transparent bleibt, ergeben sich für die meisten Entwickler zunächst kaum Umstellungsprobleme. Ein char oder String kann in Java genauso intuitiv benutzt werden wie in Sprachen, die auf dem ASCII-Zeichensatz aufbauen. Unterschiede werden vor allem dann deutlich, wenn Berührungspunkte zwischen der internen Unicode-Darstellung und der Repräsentation auf Systemebene entstehen, beispielsweise beim Lesen oder Schreiben von Textdateien. |
|
char-Literale werden grundsätzlich in einfache Hochkommata gesetzt. Daneben gibt es String-Literale, die in doppelten Hochkommata stehen. Ähnlich wie C stellt Java eine ganze Reihe von Standard-Escape-Sequenzen zur Verfügung, die zur Darstellung von Sonderzeichen verwendet werden können:
Zeichen | Bedeutung |
\b | Rückschritt (Backspace) |
\t | Horizontaler Tabulator |
\n | Zeilenschaltung (Newline) |
\f | Seitenumbruch (Formfeed) |
\r | Wagenrücklauf (Carriage return) |
\" | Doppeltes Anführungszeichen |
\' | Einfaches Anführungszeichen |
\\ | Backslash |
\nnn | Oktalzahl nnn (kann auch kürzer als drei Zeichen sein, darf nicht größer als oktal 377 sein) |
Tabelle 5.2: Standard-Escape-Sequenzen
Weiterhin können beliebige Unicode-Escape-Sequenzen der Form \uxxxx angegeben werden, wobei xxxx eine Folge von bis zu vier hexadezimalen Ziffern ist. So steht beispielsweise \u000a für die Zeilenschaltung und \u0020 für das Leerzeichen.
Ein wichtiger Unterschied zu Standard-Escape-Sequenzen besteht darin, dass Unicode-Escape-Sequenzen an beliebiger Stelle im Programm auftauchen dürfen, also auch außerhalb von char- oder String-Literalen. Wichtig ist außerdem, dass diese bereits vor der eigentlichen Interpretation des Quelltextes ausgetauscht werden. Es ist also beispielsweise nicht möglich, ein char-Literal, das ein Anführungszeichen darstellen soll, in der Form '\u0027' zu schreiben. Da die Unicode-Sequenzen bereits vor dem eigentlichen Compiler-Lauf ausgetauscht werden, würde der Compiler die Sequenz ''' vorfinden und einen Fehler melden. |
|
Java stellt vier ganzzahlige Datentypen zur Verfügung, und zwar byte, short, int und long, mit jeweils 1, 2, 4 und 8 Byte Länge. Alle ganzzahligen Typen sind vorzeichenbehaftet und ihre Länge ist auf allen Plattformen gleich.
Anders als in C sind die Schlüsselwörter long und short bereits Typenbezeichner und nicht nur Modifier. Es ist daher nicht erlaubt, long int oder short int anstelle von long bzw. short zu schreiben. Auch den Modifier unsigned gibt es in Java nicht.
Ganzzahlige Literale können in Dezimal-, Oktal- oder Hexadezimalform geschrieben werden. Ein oktaler Wert beginnt mit dem Präfix 0, ein hexadezimaler Wert mit 0x. Dezimale Literale dürfen nur aus den Ziffern 0 bis 9, oktale aus den Ziffern 0 bis 7 und hexadezimale aus den Ziffern 0 bis 9 und den Buchstaben a bis f und A bis F bestehen.
Ab Java Version 7 können ganzzahlige Literale auch in Binärschreibweise angegeben werden. Der Wert muss dazu mit dem Präfix 0b beginnen, gefolgt von den Ziffern 0 und 1. Außerdem können Ziffernfolgen nun auch Unterstriche enthalten, was die Lesbarkeit großer Zahlen erleichtern soll (z.B. 1_048_576 statt 1048576). |
|
Durch Voranstellen eines - können negative Zahlen dargestellt werden, positive können wahlweise durch ein + eingeleitet werden. Ganzzahlige Literale sind grundsätzlich vom Typ int, wenn nicht der Suffix L oder l hinten angehängt wird. In diesem Fall sind sie vom Typ long.
Tabelle 5.3 gibt eine Übersicht einiger vordefinierten Konstanten, die im Umgang mit integralen Typen hilfreich sein können.
Name | Verfügbar für | Bedeutung |
MAX_VALUE | Byte, Short, Integer, Long | Größter darstellbarer positiver Wert |
MIN_VALUE | Byte, Short, Integer, Long | Kleinster darstellbarer negativer Wert |
Tabelle 5.3: Symbolische Ganzzahlliterale
Java kennt die beiden IEEE-754-Fließkommatypen float (einfache Genauigkeit) und double (doppelte Genauigkeit). Die Länge beträgt 4 Byte für float und 8 Byte für double.
Fließkommaliterale werden immer in Dezimalnotation aufgeschrieben. Sie bestehen aus einem Vorkommateil, einem Dezimalpunkt, einem Nachkommateil, einem Exponenten und einem Suffix. Um ein Fließkommaliteral von einem integralen Literal unterscheiden zu können, muss mindestens der Dezimalpunkt, der Exponent oder der Suffix vorhanden sein. Entweder der Vorkomma- oder der Nachkommateil darf ausgelassen werden, aber nicht beide. Vorkommateil und Exponent können wahlweise durch das Vorzeichen + oder - eingeleitet werden. Weiterhin ist der Exponent, der durch ein e oder E eingeleitet wird, optional. Auch der Suffix kann weggelassen werden, wenn durch die anderen Merkmale klar ist, dass es sich um eine Fließkommazahl handelt. Der Suffix kann entweder f oder F sein, um anzuzeigen, dass es sich um ein float handelt, oder d oder D, um ein double anzuzeigen. Fehlt er, so ist das Literal (unabhängig von seiner Größe) vom Typ double.
Ab Version 7 können in Fließkommaliteralen Unterstriche verwendet werden, was die Lesbarkeit großer Zahlen erleichtern soll. So kann man beispielsweise 1_048_576.99 statt 1048576.99 schreiben. |
|
Gültige Fließkommazahlen sind:
Neben diesen numerischen Literalen gibt es noch einige symbolische in den Klassen Float und Double des Pakets java.lang. Tabelle 5.4 gibt eine Übersicht dieser vordefinierten Konstanten. NaN entsteht beispielsweise bei der Division durch 0, POSITIVE_INFINITY bzw. NEGATIVE_INFINITY sind Zahlen, die größer bzw. kleiner als der darstellbare Bereich sind.
Name | Verfügbar für | Bedeutung |
MAX_VALUE | Float, Double | Größter darstellbarer positiver Wert |
MIN_VALUE | Float, Double | Kleinster darstellbarer positiver Wert |
NaN | Float, Double | Not-A-Number |
NEGATIVE_INFINITY | Float, Double | Negativ unendlich |
POSITIVE_INFINITY | Float, Double | Positiv unendlich |
Tabelle 5.4: Symbolische Fließkommaliterale
Der Name MIN_VALUE wird im JDK uneinheitlich verwendet. Während MIN_VALUE in den Ganzzahlklassen den kleinsten darstellbaren negativen Wert darstellt, repräsentiert der Wert der gleichnamigen Konstante in den Fließkommazahlklassen den kleinsten darstellbaren positiven Wert (und liegt damit sehr nahe bei 0), vgl. Tabelle 5.3 und Tabelle 5.4. |
|
Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0 |
<< | < | > | >> | API | © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de |