träge Operandenstellen in Java [] (träge Operandenstellen in Java), Lektion, Seite 723113
https://www.purl.org/stefan_ram/pub/traege_stellen_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram

Träge Operandenstellen in Java 

Der bedingte Oder-Operator »||«

Bei diesem Operator ist die erste Stelle strikt und die zweite träge.

Bedingte Auswertung

Der Operator »||« ist der erste Operator in diesem Kurs mit bedingter Auswertung (“lazy evaluation ”) eines Operanden. Diese ermöglicht es, mit dem linken Operanden zu steuern, ob der rechte Operand ausgewertet wird! So wird in dem folgenden Programm der Aufruf »f( 1 )« nicht ausgewertet.

Main.java
public final class Main
{
public static void eval( final boolean value ){} public static boolean f( final int v )
{ java.lang.System.out.println( "f( " + v + " )" ); return true; }

public static void main( final java.lang.String[] args )
{ eval( false || f( 0 ));
eval( true || f( 1 )); }}
java.lang.System.out
f( 0 )

Bei der Ausführung der Methode »main« kommt es zu drei Operationen:

Methodenoperation (der rechte Operand wird  ausgewertet)
false || f( 0 )
false || true
— Ausgabe von »f( 0 )«
||-Operation
false || true
true
||-Operation (der rechte Operand wird nicht  ausgewertet!)
true || f( 1 )
true

Striktheit und Trägheit

Man nennt eine Operandenstelle, die nur unter bestimmten Bedingungen ausgewertet wird, auch manchmal träge. Eine, die immer ausgewertet wird, heißt strikt. Wir können also sagen, daß bei dem Operator »||« die linke Stelle strikt ist, und die rechte träge.

Methodenparameter sind immer strikt. Das heißt, das es nicht möglich ist, eine Methode zu definieren, die eines ihrer Argumente nur unter bestimmten Bedingungen auswertet. Wenn ein Methodenaufruf ausgewertet wird, dann werden immer die Werte aller Argumentausdrücke bestimmt (auch wenn diese Werte von der Methode dann gar nicht verwendet werden). Es ist also nicht möglich, eine Methode mit zwei Parametern zu definieren, die sich so verhält, wie sich der Operator »||« verhält.

Der bedingte Oder-Operator »&&«

Bedingte Auswertung

Auch dieser Operator ermöglicht es, mit dem linken Operanden zu steuern, ob der rechte Operand ausgewertet wird. So wird in dem folgenden Programm der Aufruf »f( 0 )« nicht ausgewertet.

Main.java
public final class Main
{
public static void eval( final boolean value ){} public static boolean f( final int v )
{ java.lang.System.out.println( "f( " + v + " )" ); return true; }

public static void main( final java.lang.String[] args )
{ eval( false && f( 0 ));
eval( true && f( 1 )); }}
java.lang.System.out
f( 1 )

Bei der Ausführung der Methode »main« kommt es zu drei Operationen:

&&-Operation (der rechte Operand wird nicht  ausgewertet!)
false && f( 0 )
false
Methodenoperation (der rechte Operand wird  ausgewertet)
true && f( 1 )
true && true
— Ausgabe des Textes »f( 1 )«
&&-Operation
true && true
true

Die Methode »eval« (deutsch: „werte aus!“) hat weder einen Wert noch eine Wirkung, sie ist aber nötig, um die &&-Anwendungen auswerten zu lassen, denn da eine &&-Anwendung kein Anweisungsausdruck ist, darf sie nicht direkt als Ausdruck in einer Ausdruckanweisung stehen.

Das folgende Programmbeispiel zeigt Methodenaufrufe, die genau dann ein Sternchen ausgeben, falls ihr Argumentwert "true" ist.

Main.java
public final class Main
{ public static boolean sternchen()
{ java.lang.System.out.print( "*" ); return true; } public static boolean sternchen( final boolean i )
{ return i && sternchen(); } public static void main( final java.lang.String[] args )
{ java.lang.System.out.print( "true : " ); sternchen( true ); java.lang.System.out.println();
java.lang.System.out.print( "false: " ); sternchen( false ); java.lang.System.out.println(); }}
java.lang.System.out
true : *
false:
Priorität und Assoziativität der bisher behandelten Operatoren
   ()                   Eingeklammerter Ausdruck
() Aufrufoperator
+ - Unaere vorangestellte Operatoren
L * / Multiplikation, Division
L + - Addition, Subtraktion
L && Und
L || Oder
R = Zuweisung, Anweisungsausdruck

Beispiel Bedingte Ausgabe

Mit dem &&-Operator können Methoden programmiert werden, die bisher so nicht programmiert werden konnten. Beispielsweise eine Methode zur Ausgabe der Wahrheitswerte in deutscher Sprache.

Main.java
public final class Main
{
public static void eval( final boolean value ){} public static boolean println( final java.lang.String text )
{ java.lang.System.out.println( text ); return true; } public static void println( final boolean value )
{ eval( value && println( "wahr" ));
eval( value || println( "falsch" )); } public static void main( final java.lang.String[] args )
{ println( false );
println( true ); }}
java.lang.System.out
falsch
wahr

Beispiel Verneinung

Das folgende Beispiel zeigt die Implementierung einer Verneinung (aus true  wird false  und umgekehrt) mit Hilfe des bedingten Oder-Operators.

Main.java
public final class Main
{
public static void eval( final boolean value ){} public static boolean not( final boolean value )
{ boolean result = false;
eval( value ||( result = true ));
return result; } public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( not( false ));
java.lang.System.out.println( not( true )); }}
java.lang.System.out
true
false

Die de Morgan schen Gesetze

Mathematische Schreibweise

¬( x ∨ y )⇔ ¬x ∧ ¬y
¬( x ∧ y )⇔ ¬x ∨ ¬y

Java -Schreibweise

»!( x || y )« ⇔ »!x && !y«
»!( x && y )« ⇔ »!x || !y«.
Daraus folgt:
»x || y« ⇔ »!( !x && !y )«.
»x && y« ⇔ »!( !x || !y )«.
(hierbei bedeutet „x y “ „Die Auswertung von x  hat dasselbe Verhalten wie die Auswertung von y “.)

Übungsfragen

Was gibt das folgende Programm aus?

Main.java
public final class Main
{ public static boolean t()
{ java.lang.System.out.print( "T " ); return true; } public static boolean f()
{ java.lang.System.out.print( "F " ); return false; } public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( t() && f() );
java.lang.System.out.println( f() && t() ); }}

Was gibt das folgende Programm aus?

Main.java
public final class Main
{ public static boolean t()
{ java.lang.System.out.print( "T " ); return true; } public static boolean f()
{ java.lang.System.out.print( "F " ); return false; } public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( t() || f() );
java.lang.System.out.println( f() || t() ); }}

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 stefanram723113 stefan_ram:723113 träge Operandenstellen in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723113, slrprddef723113, 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/traege_stellen_java