Referenzparameter in Java (Referenzparameter in Java), Lektion, Seite 723528
https://www.purl.org/stefan_ram/pub/referenzparameter_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Java-Kurs

Referenzparameter in Java

Der Typ eines Parameters kann auch ein Referenztyp  sein. Dies wurde ja schon im Grundkurs behandelt.

So ist es beispielsweise möglich eine statische Methode zu definieren, die einen Text in Anführungszeichen ausgibt.

Main.java
public class Main 
{ public static void printTag( final java.lang.String text ) 
{ java.lang.System.out.print( "<" + text + ">" ); } 
public static void main( final java.lang.String[] args )  
{ printTag( "TABLE" ); java.lang.System.out.println(); }}

Main [Kompassdiagramm]
               .-----------------. 
String | Main | 
-------------->| | 
text | | 
'-----------------' 


Ausgabe des Texts 
in spitzen Klammern

System.out
<TABLE>

Referenzeffekt: Die Nullreferenz als Argument

Der Aufbaukurs konnte bisher gut ohne Kenntnisse von Verzweigungsanweisungen (»if«) und Schleifenanweisungen (»while«) gelesen werden. Ab hier werden diese nun manchmal als bekannt vorausgesetzt. Weiter oben, im Grundkurs, befindet sich ein Kapitel zu Verzweigungsanweisungen (»if«) und Schleifenanweisungen (»while«).

Wenn eine Methode mit »null« aufgerufen wird, dann kann dies zu einem Laufzeitfehler führen.

Main.java

public class Main
{

public static void method( final java.lang.String string )
{ java.lang.System.out.println( string.length() );
java.lang.System.out.println( "println" ); }

public static void main( final java.lang.String[] args )
{ method( "abc" );
method( null );
java.lang.System.out.println( "println" ); }}

Protokoll
3
println
Exception in thread "main" java.lang.NullPointerException
at Main.method(Main.java:5)
at Main.main(Main.java:10)

Die obigen Methodendeklaration ist in Ordnung, es muß jedoch dann dokumentiert werden (wie dies geht, wird später behandelt werden), daß method nicht mit »null« aufgerufen werden darf.

Sonst wäre eine „nullsichere“ Variante möglich:

Main.java
public class Main
{ public static void method( final java.lang.String string )
{ if( string != null )java.lang.System.out.println( string.length() ); }
public static void main( final java.lang.String[] args )
{ method( null ); }}
java.lang.System.out
(keine Ausgabe)

Aber auch bei dieser Variante muß das Verhalten für null dokumentiert werden.

Wir können zwei Dinge festhalten:

Erstens Eine Methodendeklaration ist nicht vollständig, solange nicht auch die Dokumentation zu der Methode geschrieben wurde. Wie dies geht wurde aber in diesem Kurs bisher leider noch nicht gezeigt.

Zweitens Der Autor einer Methodendeklaration muß es sich bewußt machen, daß jedes Referenzargument auch den Wert »null« haben könnte und bewußt festlegen und dokumentieren, wie sich die Methode dann verhält.

Referenzeffekt: Aliasparameter

Wenn eine Methode mehrere Referenzparameter hat, dann kann es sein, daß zwei davon die gleiche Referenz enthalten. Man sollte also nicht davon ausgehene, daß alle Parameter unterschiedliche Referenzen enthalten. Auch hier sollte dokumentiert werden, ob es gestattet ist, daß ein Referenzwert mehrfach übergeben wird, und wie sich die Methode dann verhält.

Main.java

public final class Main

{

static void copy

( final java.lang.StringBuilder target,

final java.lang.StringBuilder source )

{ target.setLength( 0 );

target.append( source ); }

public static void main( final java.lang.String[] args )

{ final java.lang.StringBuilder alpha = new java.lang.StringBuilder( "alpha" );

final java.lang.StringBuilder gamma = new java.lang.StringBuilder( "gamma" );

java.lang.System.out.println( "alpha = \"" + alpha + "\"" );

java.lang.System.out.println( "gamma = \"" + gamma + "\"" );

java.lang.System.out.println();

copy( alpha, gamma );

java.lang.System.out.println( "alpha = \"" + alpha + "\"" );

java.lang.System.out.println( "gamma = \"" + gamma + "\"" );

java.lang.System.out.println();

copy( alpha, alpha );

java.lang.System.out.println( "alpha = \"" + alpha + "\"" ); }}

transcript
alpha = "alpha"
gamma = "gamma"

alpha = "gamma"
gamma = "gamma"

alpha = ""
Main.java

public final class Main

{

static void copy

( final java.lang.StringBuilder target,

final java.lang.StringBuilder source )

{ if( target == source )return;

target.setLength( 0 );

target.append( source ); }

public static void main( final java.lang.String[] args )

{ final java.lang.StringBuilder alpha = new java.lang.StringBuilder( "alpha" );

final java.lang.StringBuilder gamma = new java.lang.StringBuilder( "gamma" );

java.lang.System.out.println( "alpha = \"" + alpha + "\"" );

java.lang.System.out.println( "gamma = \"" + gamma + "\"" );

java.lang.System.out.println();

copy( alpha, gamma );

java.lang.System.out.println( "alpha = \"" + alpha + "\"" );

java.lang.System.out.println( "gamma = \"" + gamma + "\"" );

java.lang.System.out.println();

copy( alpha, alpha );

java.lang.System.out.println( "alpha = \"" + alpha + "\"" ); }}

transcript
alpha = "alpha"
gamma = "gamma"

alpha = "gamma"
gamma = "gamma"

alpha = "gamma"

Datenaufrufe ⁺

Das folgende Programm zeigt noch einmal wie Objekte den Aspekt des Datums (Wertes) mit dem des Programms vereinigen:

Bei Aufruf von »printLength« wird ein Objekt wie ein Datum (Wert) als Argument übergeben. In der Methode »printLength« wird es dann durch Aufruf seiner length -Methode wie ein Programm aktiviert.

Main.java

public class Main

{ public static void printLength( final java.lang.String string /* "Datum" oder "Programm"? */ )

{ java.lang.System.out.println( string.length() ); }

public static void main( final java.lang.String[] args )

{ Main.printLength( "abc" ); }}

java.lang.System.out
3

Referenzparameter und Rekursion *

Von den elementaren Typen  her ist man es vielleicht gewohnt, daß die Werte der Parameter jedes Rekursionsschrittes Kopien  der Werte der Argumente sind. Dadurch wird der vorige Zustand bewahrt, er kann in der neuen Rekursionstiefe nicht verändert werden, und eine Rückkehrt zur vorigen Rekursionstiefe bedeutet die Wiederherstellung  des vorherigen Zustandes.

Bei Referenztypen  wird der Zustand eines Objektes bei der Übergabe an Parameter aber nicht  mehr kopiert, es wird nur noch die Referenz kopiert. Daher ist es bei rekursiven Algorithmen in Java  oft nötig, den Zustand am Anfang eines Rekursionsschrittes gegebenenfalls manuell zu kopieren und am Ende eines Rekursionsschrittes den vorherigen Zustand manuell wiederherzustellen.

?   Übungsfrage

Was ist die Ausgabe des folgenden Programms?

Main.java

public final class Main
{

public static void m( java.lang.StringBuilder v )
{ v.replace( 0, java.lang.Integer.MAX_VALUE, "gamma" );
java.lang.System.out.println( v );
v = new java.lang.StringBuilder( "delta" );
java.lang.System.out.println( v );
v.replace( 0, java.lang.Integer.MAX_VALUE, "epsilon" );
java.lang.System.out.println( v ); }

public static void main( final java.lang.String[] args )
{ java.lang.StringBuilder v = new java.lang.StringBuilder( "alpha" );
java.lang.System.out.println( v );
m( v );
java.lang.System.out.println( v ); }}

?   Übungsfrage

Was ist die Ausgabe des folgenden Programms?

Main.java

public final class Main
{

public static void m( double x, final java.awt.geom.Point2D.Double p )
{ x = 2; p.x = 2; }

public static void main( final java.lang.String[] args )
{ final double x = 0.0;
final java.awt.geom.Point2D.Double p = new java.awt.geom.Point2D.Double( 0.0, 0.0 );
m( x, p );
java.lang.System.out.println( x );
java.lang.System.out.println( p.x ); }}

Übungsaufgaben

Ermittlung der Länge eines Strings
Schreiben Sie eine Methode, welche die Länge  eines ihr als Argumentwert übergebenen String-Objekts zurückgibt.
Zusatzaufgabe: Schreiben Sie die Methode so, daß auch übergebene StringBuilder-Objekte akzeptiert werden.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723528 stefan_ram:723528 Referenzparameter in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723528, slrprddef723528, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/referenzparameter_java