Unveränderliche Objekte mit versteckten Felder am Beispiel der Klasse "java.lang.String"
Die Klasse »java.lang.String« ist vermutlich die am häufigsten verwendete Klasse in Java. Daher lohnt es sich, sich ein wenig näher mit ihr zu beschäftigen und die wichtigsten String-Methoden kennenzulernen!
Die Verkettung akzeptiert als rechten Operanden auch einen Ausdruck eines beliebigen Referenztyps. Sie ruft dann die Methode "toString()" des Objektes auf und verwendet den so erhaltenen Text.
Main.java
public class Main
{ final public static void main( java.lang.String[] args )
{ java.lang.System.out.println( ":" + 2 );
java.lang.System.out.println( ":" + java.lang.System.out );
java.lang.System.out.println( ":" + java.lang.System.out.getClass() ); }}java.lang.System.out
:2
:java.io.PrintStream@601bb1
:class java.io.PrintStream
Der Plusoperator »+« erzeugt bei Verwendung mit Operanden der Klasse »java.lang.String« unter Umständen zur Laufzeit eine neues Objekt (welches das Ergebnis der Verkettung repräsentiert). Dieses Programm zeigt also eine Möglichkeit zum Erzeugen neuer Objekte während des Programmablaufs. Auch verschiedene andere Operationen, deren Ergebnis den Typ »java.lang.String« haben, erzeugen neue Objekte. Wir werden dies im folgenden aber nicht immer erwähnen.
Der Typ eines String-Literals (wie z.B. "abc") ist java.lang.String.
Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( "Hallo!".length() ); }}transcript
6
Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( "With.java.txt".replace( ".", "_" )); }}transcript
With_java_txt
Main.java
public class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( "With.java.txt".indexOf( "." )); }}transcript
4
Die Änderungsmetaphorik
Über Wertmethoden, die eigentlich keine Veränderung an ihrem Zielobjekt vornehmen, spricht man oft in einer Weise, die den Eindruck einer Änderung hervorrufen könnten.
Beispielsweise klingt der Name der Methode »replace« so als würde sie eine Veränderung vornehmen. Man spricht auch so über diese Methode und sagt, daß sie etwas „ersetze“.
Tatsächlich ergibt sie aber nur einen neuen Text und ändert nichts an ihrem Zielobjekt.
Man beschreibt hier die Veränderung des Ergebnisses im Vergleich mit dem Zielobjekt, wenn man hier von einer „Änderung“ spricht. Genau genommen wird dabei nichts verändert, weswegen es sich hierbei nicht um eine Wirkung (Veränderung) handelt.
Übungsfragen ⃗
- Ausdrücke
- Geben Sie zu den folgenden Ausdrücken jeweils an:
- Handelt es sich um einen Wertausdruck (einen Ausdruck, dessen Auswertung einen Wert ergibt)?
- Handelt es sich um einen Wirkausdruck (einen Ausdruck, dessen Auswertung eine Wirkung hat)? (soweit erkennbar)
- Welchen Datentyp hat der Ausdruck (falls es sich um einen Wertausdruck handelt)?
- Welchen Wert hat der Ausdruck (falls es sich um einen Wertausdruck handelt)?
o »"Hallo!".length()«
o »"a=[ 0 ]".replace( "a", "b" )«
Übungsaufgaben ⃗
- Systeminformationen ausgeben
- Der Wert des Ausdrucks »java.lang.System.getProperties()« ist ein Objekt, das eine Sammlung von Informationen über den Computer repräsentiert.
- Rufen Sie die Methode »toString()« jenes Objektes auf und geben Sie das Ergebnis aus. Das Ergebnis jenes Aufrufs ist eine Darstellung des Objekts als java.lang.String-Objekt, in welchem die Eigenschaften durch Kommas getrennt sind. Dies ist aber unübersichtlich.
- Rufen Sie daher nun die Metode »replace« jenes java.lang.String-Objekts mit den beiden Argumenten »","« und »java.lang.System.getProperty( "line.separator" )« auf, um alle Kommas durch Zeilentrenner zu ersetzen und geben Sie das Ergebnis aus, um so eine Ausgabe zu erhalten, in der nicht alle Systeminformation in einer einzigen Zeile stehen.
- Aussprachehinweis
- property ˈprɑp ɚ ti
- separator ˌsɛp ə ˈret ɚ
- Dokumentation der Klasse »java.lang.String« nutzen
- Die Klasse »java.lang.String« enthält nicht-statische Methoden mit dem Namen »indexOf«, um die Position eines Zeichens in einer Zeichenfolge zu ermitteln, dabei wird von vorne nach hinten gesucht. Finden Sie eine entsprechende Methode, die aber von hinten nach vorne sucht, und schreiben Sie ein kleines Programm oder eine Programmzeile, um diese Methode auszuprobieren.
- (Die Bestimmung der Position erfolgt auch bei einer Suche von hinten nach vorne so, daß von vorne nach hinten aufsteigend gezählt wird.)
- Suchen Sie sich eine weitere, bisher noch nicht behandelte, nicht-statische Methode dieser Klasse »java.lang.String« aus und schreiben Sie ein kleines Programm oder eine Programmzeile, um diese auszuprobieren.
- Rechtsbündiges Formatieren *
- Schreiben Sie eine statische Klassenmethode "printRight", die einen int-Wert "number" ausgibt. Dabei sollen der Textdarstellung des Wertes so viele Leerzeichen vorangestellt werden, daß insgesamt immer zehn Zeichen ausgegeben werden. (Dies soll möglichst ohne Schleifen und mit Methoden der Klasse »java.lang.String« programmiert werden.)
Main.java
public class Main
{ public static void printRight( final int number )
{ /* ... */ }
public static void main( java.lang.String[] args )
{ printRight( 32 ); java.lang.System.out.println();
printRight( 8 ); java.lang.System.out.println();
printRight( 121 ); java.lang.System.out.println(); }}System.out
32
8
121
Zusatzaufgaben
- Textsuche
- Schreiben Sie eine Methode, die einen Text vom Typ »String« als Argument akzeptiert. Es soll angenommen werden, daß in diesem Text genau einmal die Zeichenfolge »<alpha>« und später genau einmal die Zeichenfolge »</alpha>« vorkommt. Die Methode soll den Text zurückgeben, der zwischen »<alpha>« und »</alpha>« steht.
- Datum analysieren
- Ein Datum werde in der Form 〈Jahr 〉 "-" 〈Monat 〉 "-" 〈Tag 〉 angegeben, beispielsweise als "1970-12-1". Schreiben Sie eine Methode, die ein Datum in dieser Form entgegennimmt und das Jahr ausgibt.
- Datum analysieren 1
- Ein Datum werde in der Form 〈Jahr 〉 "-" 〈Monat 〉 "-" 〈Tag 〉 angegeben, beispielsweise als "1970-12-1". Schreiben Sie eine Methode, die ein Datum in dieser Form entgegennimmt und den Monat als int -Wert zurückgibt. (Wandlung nach int ist mit java.lang.Integer.valueOf möglich.) (Der int -Wert eines java.lang.String -Objekts »s« mit einem ganzzahligen Numerale [wie »"21"«] ist »java.lang.Integer.parseInt( s )«.)
- Würfel
- Eine Wurfbeschreibung der Form "W12" steht für einen Wurf eines Würfels mit 12 Seiten. Schreiben Sie eine Methode, die zu einer solchen Wurfbeschreibung einen Wurf simuliert und die Summe der geworfenen Augenzahlen ergibt. (Wandlung nach int ist mit java.lang.Integer.valueOf möglich.) (Der int -Wert eines java.lang.String -Objekts »s« mit einem ganzzahligen Numerale [wie »"21"«] ist »java.lang.Integer.parseInt( s )«.)
- Würfel 1
- Eine Wurfbeschreibung der Form "2W6" steht für einen Wurf von zwei Würfeln mit jeweils 6 Seiten. Schreiben Sie eine Methode, die zu einer solchen Wurfbeschreibung einen Wurf simuliert und die Summe der geworfenen Augenzahlen ergibt. (Wandlung nach int ist mit java.lang.Integer.parseInt möglich.) (Der int -Wert eines java.lang.String -Objekts »s« mit einem ganzzahligen Numerale [wie »"21"«] ist »java.lang.Integer.parseInt( s )«.)
Zusatzaufgaben
- Namen analysieren
- Ein Name werde in der Form 〈Vornamen 〉 " " 〈Nachname 〉 angegeben, beispielsweise als "Frank Werner Meyer". Schreiben Sie eine Methode, die einen Namen in dieser Form entgegennimmt und in der Form 〈Nachname 〉 ", " 〈Vornamen 〉, also beispielsweise als "Meyer, Frank Werner", den Namen als String -Objekt zurückgibt.
- Verb ermitteln
- Schreiben Sie eine Abbildungs-Methode, die zu einer Angabe einer Methode, die einen Punkt enthält, wie beispielsweise den Text "Math.abs", das Verb, wie beispielsweise den Text "abs", ergibt.
Main.java
public final class Main
{ public static java.lang.String simpleMethodName( final java.lang.String text )
{ /* ... */ }
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( simpleMethodName( "Math.abs" ));
java.lang.System.out.println( simpleMethodName( "Math.random" )); }}java.lang.System.out
abs
random- Verb ermitteln (1)
- Stellen Sie sicher, daß sich auch bei Angaben mit mehr als einem Punkt, wie der Angabe "System.out.println", der Teil nach dem letzten Punkt als Verb ergibt.
Main.java
public final class Main
{ public static java.lang.String simpleMethodName( final java.lang.String text )
{ /* ... */ }
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( simpleMethodName( "Math.abs" ));
java.lang.System.out.println( simpleMethodName( "Math.random" ));
java.lang.System.out.println( simpleMethodName( "System.out.println" )); }}java.lang.System.out
abs
random
println- Verb ermitteln (2)
- Stellen Sie sicher, daß sich bei Angaben ohne einen Punkt, wie der Angabe "print", die gesamte Angabe als Verb ergibt.
Main.java
public final class Main
{ public static java.lang.String simpleMethodName( final java.lang.String text )
{ /* ... */ }
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( simpleMethodName( "Math.abs" ));
java.lang.System.out.println( simpleMethodName( "Math.random" ));
java.lang.System.out.println( simpleMethodName( "System.out.println" ));
java.lang.System.out.println( simpleMethodName( "print" )); }}java.lang.System.out
abs
random
println
print