Newer
Older
<chapter annotations="slide" version="5.1" xml:id="sd1_chap_Statements"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:ns="http://docbook.org/ns/transclusion"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<info>
<abstract>
<para>Purposes of statements:</para>
<para>Declaring variables and assigning values.</para>
<para>Control <emphasis role="bold">whether</emphasis> code will be
executed.</para>
<para>Control <emphasis role="bold">how often</emphasis> code will be
executed.</para>
</abstract>
</info>
<figure xml:id="sd1_fig_StatementEndSemicolon">
<para>Statement's body terminated by <quote>;</quote></para>
<programlisting language="none">{statement};</programlisting>
</figure>
<figure xml:id="sd1_fig_StatementDeclareVariable">
<title>Statement examples: Declaring and assigning variables</title>
<glossterm>Variable declaration:</glossterm>
<glossdef>
<programlisting language="java">int a;</programlisting>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Value assignment:</glossterm>
<glossdef>
<programlisting language="java">a = 33;</programlisting>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Combined declaration and assignment:</glossterm>
<glossdef>
<programlisting language="java">int a = 33;</programlisting>
</glossdef>
</glossentry>
</glosslist>
</figure>
<figure xml:id="sd1_fig_StatementVsExpression">
<title>Expression <abbrev>vs.</abbrev> statement</title>
<glosslist>
<glossentry>
<glossterm>Expression:</glossterm>
<glossdef>
<programlisting language="java">a - 4</programlisting>
</glossdef>
</glossentry>
<glossentry>
<glossterm>Statement:</glossterm>
<glossdef>
<programlisting language="java">b = a - 4;</programlisting>
<para>Notice the trailing <quote><code>;</code></quote>.</para>
</glossdef>
</glossentry>
</glosslist>
</figure>
<figure xml:id="sd1_fig_MultiStmtPerLine">
<title>Multiple statements per line</title>
<programlisting language="java">a = b + 3; b = a - 4;</programlisting>
<para>Discouraged by good coding practices:</para>
</figure>
<figure xml:id="sd1_fig_DebugMultiStmtPerLine">
<title>Debugging multiple statements per line</title>
<mediaobject>
<imageobject>
<imagedata fileref="Fig/multipleStatementPerLine.svg"/>
</imageobject>
</mediaobject>
</figure>
<figure xml:id="sd1_fig_Blocks">
<title>Blocks</title>
<programlisting language="java">double initialAmount = 34;
final double interestRate = 1.2; // 1.2%
System.out.println("Interest:" + initialAmount * interestRate / 100);
final double interestRate = 0.8; // 0.8%
System.out.println("Interest:" + initialAmount * interestRate / 100);
<informaltable border="1">
<tr>
<td><itemizedlist>
<listitem>
<para>Defining scopes</para>
</listitem>
<listitem>
<para>Unit of work</para>
</listitem>
</itemizedlist></td>
<td><itemizedlist>
<listitem>
<para><code language="java">if</code>: Conditional block
execution.</para>
<para><code language="java">for</code> / <code
language="java">while</code>: Repeated block execution.</para>
</listitem>
</itemizedlist></td>
</tr>
</informaltable>
</figure>
<section xml:id="sd1_sect_statements_if">
<td valign="top"><programlisting language="java">double saving = 320.00;
System.out.println("Done!");</programlisting></td>
<td rowspan="2" valign="top"><mediaobject>
<figure xml:id="sd1_fig_ifSyntax">
<title><code language="java">if</code> syntax</title>
<programlisting language="java">if (booleanExpression)
(block | statement)</programlisting>
</figure>
<section xml:id="sd1_sect_else">
<title>if-then-<code>else</code></title>
<figure xml:id="sd1_fig_ifElse">
<title><code language="java">if</code> ... <code
<informaltable border="1">
<tr>
<td valign="top"><programlisting language="java">double saving = 320.00;
if (1000 <= saving <co linkends="sd1_fig_ifElse-1"
xml:id="sd1_fig_ifElse-1-co"/>) { <co
linkends="sd1_fig_ifElse-2" xml:id="sd1_fig_ifElse-2-co"/>
// Rich customer, 1,2% interest rate
System.out.println(
} <co linkends="sd1_fig_ifElse-3" xml:id="sd1_fig_ifElse-3-co"/> else { <co
linkends="sd1_fig_ifElse-4" xml:id="sd1_fig_ifElse-4-co"/>
System.out.println("Done!");</programlisting><screen>Interest:2.56
<td valign="top"><mediaobject>
<imageobject>
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
</imageobject>
</mediaobject></td>
</tr>
</informaltable>
<calloutlist role="slideExclude">
<callout arearefs="sd1_fig_ifElse-1-co" xml:id="sd1_fig_ifElse-1">
<para>Decision on boolean expression.</para>
</callout>
<callout arearefs="sd1_fig_ifElse-2-co" xml:id="sd1_fig_ifElse-2">
<para>Conditional execution of on block or single
statement.</para>
</callout>
<callout arearefs="sd1_fig_ifElse-3-co" xml:id="sd1_fig_ifElse-3">
<para>Required branch being executed in case of boolean expression
being true.</para>
</callout>
<callout arearefs="sd1_fig_ifElse-4-co" xml:id="sd1_fig_ifElse-4">
<para>Optional branch corresponding to boolean expression being
false.</para>
</callout>
</calloutlist>
</figure>
<figure xml:id="sd1_fig_ifElseSyntax">
<title><code language="java">if ... else</code> syntax</title>
<programlisting language="java">if (booleanExpression)
(block | statement)
(block | statement) ] <co linkends="sd1_fig_ifElseSyntax-1"
xml:id="sd1_fig_ifElseSyntax-1-co"/></programlisting>
<calloutlist role="slideExclude">
<callout arearefs="sd1_fig_ifElseSyntax-1-co"
xml:id="sd1_fig_ifElseSyntax-1">
<para>The <quote>[...]</quote> pair of braces denotes an optional
clause that may or may not be present.</para>
<para>Thus only the first part <quote><code language="java">if
(booleanExpression) (block | statement)</code></quote> is
mandatory.</para>
</callout>
</calloutlist>
</figure>
<figure xml:id="sd1_fig_bestPracticeCompareEquals">
<title>Best practices comparing for equality</title>
<programlisting language="java">if (4 == variable) ...</programlisting>
<programlisting language="java">if (variable == 4) ... <co
linkends="sd1_fig_bestPracticeCompareEquals-1"
xml:id="sd1_fig_bestPracticeCompareEquals-1-co"/></programlisting>
<calloutlist role="slideExclude">
<callout arearefs="sd1_fig_bestPracticeCompareEquals-1-co"
xml:id="sd1_fig_bestPracticeCompareEquals-1">
<para>Some programming languages allow for interpreting integer
values as logical expressions. In »C / C++« for example an
<code>int</code> value of zero is equivalent to <code>false</code>
and nonzero values evaluate to <code>true</code>. Consider the
following snippet:</para>
<programlisting language="c">if (variable = 4) {...} /* Just a single "=" rather then "==" */</programlisting>
<para>A <xref linkend="glo_Java"/> compiler will flag this as a
compile time error. On contrary in »C / C++« this is perfectly
correct code: The term <code>variable = 4</code> having a nonzero
value of 4 evaluates to <code>true</code> which in real code would
most likely be a bug. Subject to choosing compiler warning options
the possible damage may be mitigated depending on the observer's
degree of pedantry.</para>
<para>Changing the order however even in »C / C++« results in a
compile time error since we cannot assign a value to a
literal:</para>
<programlisting language="java">if (4 = variable) {...} // Compile time error, even in C/C++</programlisting>
<para>We are thus able to avoid this type of error in the first
place.</para>
</callout>
</calloutlist>
<qandaset defaultlabel="qanda" xml:id="sd1_qanda_betterSimpleMath">
<title>Providing better display</title>
<qandadiv>
<qandaentry>
<question>
<para>We reconsider <xref
linkend="sd1_qanda_simpleMath"/>:</para>
<th>Output</th>
</tr>
<tr>
<td valign="top"><programlisting language="java">int a = -4,
b = 100;
System.out.println(a + "+" + b+ "=" + (a + b));</programlisting></td>
<td valign="top"><screen>-4+100=96</screen></td>
</tr>
</informaltable>
<para>Unfortunately a negative value yields:</para>
<tr>
<td valign="top"><programlisting language="java">int a = 100,
b = -4;
System.out.println(a + "+" + b + "=" + (a + b));</programlisting></td>
<td valign="top"><screen>100+-4=96</screen></td>
</tr>
</informaltable>
<para>This result looks awkward. Modify the code to see
<code>100-4=96</code> in such cases. You may reconsider the
findings from <xref linkend="sd1QandaBracesInPrintln"/>.</para>
<answer>
<para>The following simple solution does not work:</para>
<informaltable border="0">
<tr>
<th>Source code</th>
<tr>
<td valign="top"><programlisting language="java">int a = 100,
b = -4;
if (b < 0) {
System.out.println(a + b + "=" + (a + b));
} else {
System.out.println(a + "+" + b + "=" + (a + b));
}</programlisting></td>
<td valign="top"><screen>96=96</screen></td>
</tr>
</informaltable>
<para>Since <code language="java">a</code> and <code
language="java">b</code> are both variables of type <code
language="java">int</code> they get added rather than string
style concatenated:</para>
<programlisting language="none">System.out.println(a + b + "=" + (a + b));
<emphasis role="red">╲ ╱ ╱ ╲ ╱
96 ╱ 96
╲ ╱ ╱
"96=" ╱
╲ ╱
"96=96"</emphasis></programlisting>
<para>Resolving this issue may be effected by adding an empty
linkend="sd1_qanda_betterSimpleMathEmptyString-1-co"/> forcing
<xref linkend="glo_Java"/> to use the concatenation
<quote>+</quote> operator in favour of the arithmetic
one:</para>
<programlisting language="none">System.out.println(a + ""<co
xml:id="sd1_qanda_betterSimpleMathEmptyString-1-co"/> + b + "=" + (a + b));
<emphasis role="red">╲ ╱ ╱ ╲ ╱
"100" ╱ 96
╲ ╱ ╱
"100-4" ╱
╲ ╱
"100-4=96"</emphasis></programlisting>
<informaltable border="0">
<tr>
<th>Source code</th>
<th>Output</th>
</tr>
<tr>
<td valign="top"><programlisting language="java">int a = 100,
System.out.println(a + "" + b + "=" + (a + b));
} else {
System.out.println(a + "+" + b + "=" + (a + b));
}</programlisting></td>
<td valign="top"><screen>100-4=96</screen></td>
</tr>
</informaltable>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<qandaset defaultlabel="qanda" xml:id="sd1_qanda_booleanEqual">
<title>Comparing for equality</title>
<qandadiv>
<qandaentry>
<question>
<para>Copy the following snippet into your <xref
linkend="glo_IDE"/>:</para>
<programlisting language="java">int count = 1;
if (count = 4) { // is count equal to 4?
System.out.println("count is o.K.");
}</programlisting>
<para>The <xref linkend="glo_Java"/> compiler will indicate an
error:</para>
Required: <emphasis role="red">boolean</emphasis>
Found: <emphasis role="red">int</emphasis></screen>
<para>Explain its cause in detail by examining the <code
language="java">count = 4</code> expression.</para>
<tip>
<para><xref linkend="glo_Java"/> provides two similar looking
operators <code language="java">=</code> and <code
language="java">==</code> having (totally) different
semantics.</para>
</tip>
</question>
<para>The two operators <code language="java">=</code> and <code
language="java">==</code> are <emphasis>completely</emphasis>
unrelated:</para>
<glosslist>
<glossentry>
<glossterm><code language="java">=</code></glossterm>
<glossdef>
<para>This is being called the assignment operator. A
typical statement reads <code language="java">a =
34</code> assigning the <code language="java">int</code>
value <code language="java">34</code> to a variable <code
language="java">a</code>.</para>
<para>Note this operator's semantics being completely
different from even elementary math syntax.
Consider:</para>
<informalequation>
<m:math display="block">
<m:mrow>
<m:mi>x</m:mi>
<m:mi>2</m:mi>
</m:msup>
</m:mrow>
</m:math>
</informalequation>
<para>In math <quote>=</quote> denotes the equality of
objects <abbrev>e.g.</abbrev> values, sets, functions and
so on.</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm><code language="java">==</code></glossterm>
<glossdef>
<para>The comparison operator matching the usual math
semantics comparing:</para>
<itemizedlist>
<listitem>
<para><xref linkend="glo_Java"/> primitive types for
equality of value.</para>
</listitem>
<listitem>
<para><xref linkend="glo_Java"/> objects for
identity.</para>
</listitem>
</itemizedlist>
<para>In particular an expression like <code
language="java">count == 4</code> is of type boolean being
either <code language="java">true</code> or <code
</glossdef>
</glossentry>
</glosslist>
<para>More formally the expression <code language="java">count =
4</code> is of type <code language="java">int</code> evaluating
to 4 (surprise!). However an <code language="java">if
(...)</code> operates on <code language="java">boolean</code>
values only and <code language="java">if (4)</code> thus does
not make sense at all. The code in question may therefore be
re-written as:</para>
<programlisting language="java">int count = 1;
int countAssignment = (count = 4); // Assigning expression count = 4 to variable countAssignment.
if (countAssignment) { <emphasis role="red">// Error: An int is not a boolean!</emphasis>
System.out.println("count is o.K.");
}</programlisting>
<para>Since the assignment operator is being evaluated from
int countAssignment = count = 4; // Assigning expression count = 4 to variable countAssignment
...</programlisting>
<para>This code is equivalent to its counterpart with respect to
compilation. The comment <quote>is count equal to 4?</quote> is
thus misleading: The intended comparison requires using the
<quote>==</quote> operator rather than an assignment operator
<quote>=</quote>. Changing it the resulting expression is indeed
of type <code language="java">boolean</code>:</para>
<programlisting language="java">int count = 4 + 3;
final boolean test = (count == 4); // Now using "==" (comparison) in favour of "=" (assignment)
System.out.println("test=" + test);</programlisting>
<para>Again we may omit braces here due to operator priority
rules:</para>
final boolean test = count == 4; // Now using "==" (comparison) in favour of "=" (assignment)
...</programlisting>
<para>The <code language="java">boolean</code> variable <code
language="java">test</code> will receive a value of <code
language="java">false</code> as expected. Thus our initial code
just needs a tiny modification replacing the assignment operator
«<code language="java">=</code>» by the comparison operator
«<code language="java">==</code>»:</para>
<programlisting language="java">int count = 1;
if (count == 4) { // is count equal to 4?
System.out.println("count is o.K.");
}</programlisting>
<note xml:id="sd1_note_useLiteralEqualsVariable">
<para>In contrast to <xref linkend="glo_Java"/> some
programming languages like C and C++ allow for integer values
in <code language="java">if (...)</code> conditionals:</para>
<programlisting language="c">#include <stdio.h>
int main(int argc, char **args) {
int a = 3;
if (a = 4) {
printf("a has got a value of 4\n");
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
<para>The integer expression <code language="java">count =
4</code> has got a value of 4. Integer values inside an <code
language="java">if (...)</code> statement will be evaluated
as:</para>
<glosslist>
<glossentry>
<glossterm>true</glossterm>
<glossdef>
<para>if the expression's value differs from zero</para>
</glossdef>
</glossentry>
<glossentry>
<glossterm>false</glossterm>
<glossdef>
<para>if the expression's value equals zero</para>
</glossdef>
</glossentry>
</glosslist>
<para>Thus in C and C++ the expression <code
language="java">if(count = 4)</code> will always evaluate to
<code language="java">true</code> irrespective of the variable
<code language="java">count</code>'s initial value. Most
important: The C compiler will not issue an error or warning
unless non-default, more restrictive compile time warning
options are being activated. Consider this widely used
«feature» to be dangerous at best.</para>
<para>For this reason it is good practice always using <code
language="java">if (4 == count)</code> rather than <code
language="java">if (count == 4)</code>: Even in C you cannot
assign a value to a constant literal. Thus an accidentally
mistyped <code language="java">if (4 = count)</code> statement
will definitively result in a compile time error most likely
saving its author from tedious debugging.</para>
</note>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<figure xml:id="sd1_fig_IfOmitBlocks">
<title>Single statement branches</title>
<para>Branches containing exactly one statement don't require a block
definition.</para>
<programlisting language="java">double initialAmount = 3200;
System.out.println("Interest:" + 1.2 * initialAmount / 100);
else if (1000 <= initialAmount)
System.out.println("Interest:" + 0.8 * initialAmount / 100);
System.out.println("Interest:" + 0);</programlisting>
<figure xml:id="sd1_fig_ifElseNested">
<title>Nested <code language="java">if ... else</code></title>
<informaltable border="1">
<tr>
<td valign="top"><programlisting language="java">if ('A' == grade || 'B' == grade) {
result = "Excellent";
} else {
if ('C' == grade) {
result = "O.k.";
} else {
if ('D' == grade) {
result = "Passed";
} else {
result = "Failed";
}
}
}</programlisting></td>
<td valign="top"><mediaobject>
<imageobject>
</imageobject>
</mediaobject></td>
</tr>
</informaltable>
</figure>
</section>
<section xml:id="sd1_sect_elseif">
<title>Using <code language="java">else if</code></title>
<figure xml:id="sd1_fig_ifElse_else">
<title>Enhanced readability: <code language="java">if ... else if ...
else</code></title>
<informaltable border="1">
<tr>
<td valign="top"><programlisting language="java">if ('A' == grade || 'B' == grade) {
result = "Excellent";
} else if ('C' == grade) {
result = "O.k.";
} else if ('D' == grade) {
result = "Passed";
} else {
result = "Failed";
}</programlisting></td>
<td valign="top"><mediaobject>
<imageobject>
</imageobject>
</mediaobject></td>
</tr>
</informaltable>
</figure>
<figure xml:id="sd1_fig_ifElse_elseSyntax">
<title><code language="java">if ... else if ... else</code>
syntax</title>
<programlisting language="java">if (booleanExpression)
(block | statement)
[else if (booleanExpression)
(block | statement) ]* <co linkends="sd1_fig_ifElse_elseSyntax-1"
(block | statement) ] <co linkends="sd1_fig_ifElse_elseSyntax-2"
xml:id="sd1_fig_ifElse_elseSyntax-2-co"/></programlisting>
<calloutlist role="slideExclude">
<callout arearefs="sd1_fig_ifElse_elseSyntax-1-co"
xml:id="sd1_fig_ifElse_elseSyntax-1">
<para>The pair of braces [...] indicates an optional clause. The
asterisk <quote>*</quote> indicates an arbitrary number of
repetitions (zero to infinity).</para>
</callout>
<callout arearefs="sd1_fig_ifElse_elseSyntax-2-co"
xml:id="sd1_fig_ifElse_elseSyntax-2">
<para>The second pair of braces [...] again indicates an optional
clause.</para>
<para>Thus only the <quote><code language="java">if
(booleanExpression) (block | statement)</code></quote> clause is
mandatory.</para>
</callout>
</calloutlist>
</figure>
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
<qandaset defaultlabel="qanda" xml:id="sd1_qanda_replaceElseIf">
<title>Replacing <code language="java">else if (...){...}</code> by
nested <code language="java">if ... else</code> statements</title>
<qandadiv>
<qandaentry>
<question>
<para>A computer newbie did not yet read about the <code
language="java">else if(...)</code> branch construct but
nevertheless tries to implement the following logic:</para>
<programlisting language="java">if (a < 7) {
System.out.println("o.K.");
} else if (5 == b) {
System.out.println("Maybe");
} else {
System.out.println("Wrong!");
}</programlisting>
<para><code language="java">a</code> and <code
language="java">b</code> are supposed to be <code
language="java">int</code> variables. Please help our newbie
using just <code language="java">if(...){...} else {...} </code>
avoiding <code language="java"><emphasis role="red">else
if</emphasis>(...) {}</code> branch statements!</para>
<tip>
<para>As the title suggests you may want to nest an
<quote>inner</quote> <code language="java">if(...)</code>
inside an <quote>outer</quote> one.</para>
</tip>
</question>
<answer>
<para>The solution requires replacing the <code
language="java">else if(...)</code> branch by a nested <code
language="java">if(...){ ...} else {...}</code> statement by
moving the final <code language="java">else</code> block into
the nested one.</para>
<programlisting language="java">if (a < 7) {
System.out.println("o.K.");
} else {
if (5 == b) {
System.out.println("Maybe");
} else {
System.out.println("Wrong!");
}
}</programlisting>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<figure xml:id="sd1_fig_useScannerClass">
<title>User input recipe</title>
<informaltable border="0">
<tr>
<td valign="top"><programlisting language="java">import java.util.Scanner;
public class App {
public static void main(String[] args){
System.out.print("Enter a value:");
final int value = scan.nextInt();
System.out.println("You entered "
+ value);
You entered 123</screen><para>See <methodname
xlink:href="javaapi://java.util.Scanner#nextBoolean()">nextBoolean()</methodname>,
xlink:href="javaapi://java.util.Scanner#nextByte()">nextByte()</link></methodname>
and friends.</para></td>
</tr>
</informaltable>
</figure>
<qandaset defaultlabel="qanda" xml:id="sw1QandaPostExamBonuspoints">
<title>Post modifying an exam's marking</title>
<qandadiv>
<qandaentry>
<question>
<para>A lecturer marks an exam having a maximum of 12 reachable
points:</para>
<informaltable border="1" width="25%">
<th>Mark</th>
</tr>
<tr>
<td>Aaron</td>
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
<td>3</td>
</tr>
<tr>
<td>Maureen</td>
<td>11</td>
</tr>
<tr>
<td>Sally</td>
<td>1</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>
</informaltable>
<para>The lecturer is dissatisfied with the overall result. He
wants to add 3 bonus points but still keeping the maximum of 12
points to be reachable:</para>
<informaltable border="1" width="25%">
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
<tr>
<th>Name</th>
<th>Mark</th>
<th>3 bonus points augmented mark</th>
</tr>
<tr>
<td>Aaron</td>
<td>3</td>
<td>6</td>
</tr>
<tr>
<td>Maureen</td>
<td>11</td>
<td><emphasis role="red">12</emphasis></td>
</tr>
<tr>
<td>Sally</td>
<td>1</td>
<td>4</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
</informaltable>
<para>Complete the following code by assigning this modified
number of points to the variable <code
language="java">newResult</code>.</para>
<programlisting language="java">public static void main(String[] args) {
final int maximumPoints = 12;
final int pointsToAdd = 3;
}</programlisting>
<orderedlist>
<listitem>
<para>The basic task is to add up the values of <code
language="java">pointsReached</code> and <code
language="java">pointsToAdd</code>. This sum however must
not exceed the <code language="java">maximumPoints</code>
limit. We use an <code language="java">if</code> statement
for constraint safeguarding:</para>
<programlisting language="java">public static void main(String[] args) {
final int maximumPoints = 12;
final int pointsToAdd = 3;