diff --git a/Doc/Sd1/languageFundamentals.xml b/Doc/Sd1/languageFundamentals.xml index 35455873146a54acdb693b204e70b8bafbfdddc3..433dca253b73929bfcdad2c79703292ae1106b79 100644 --- a/Doc/Sd1/languageFundamentals.xml +++ b/Doc/Sd1/languageFundamentals.xml @@ -769,6 +769,43 @@ i = b; // Error: int and boolean are incompatible types i = "Hello"; // Even worse: Assigning a String to an int</programlisting> </figure> + <figure xml:id="sd1_fig_final"> + <title>Using final</title> + + <glosslist> + <glossentry> + <glossterm>Bad</glossterm> + + <glossdef> + <programlisting language="java">double pi = 3.141592653589793; + ... +pi = -4; // Woops, accidential redefinition</programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Good:</glossterm> + + <glossdef> + <para><programlisting language="java">final double pi = 3.141592653589793; +... +pi = -4; // Compile time error: + // Cannot assign a value to final variable 'pi'</programlisting></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Even better</glossterm> + + <glossdef> + <para><programlisting language="java">final double PI = 3.141592653589793; // Coding style (Best practices): + // Using capital letters for constant variable +...</programlisting></para> + </glossdef> + </glossentry> + </glosslist> + </figure> + <qandaset defaultlabel="qanda" xml:id="sd1_qanda_typeAssignCompat"> <title>Assignment and type safety</title> @@ -1004,13 +1041,144 @@ int i = (int) d; // Explicit cast double to int</programlisting> </informaltable> </figure> + <qandaset defaultlabel="qanda" xml:id="sw1QandaTinyIntRepresent"> + <title>Inventing <code>tinyint</code>.</title> + + <qandadiv> + <qandaentry> + <question> + <para>Suppose <xref linkend="glo_Java"/> was offering a signed integer type <code>tinyint</code> using 3-bit 2-complement representation.</para> + + <orderedlist> + <listitem> + <para>Write down all possible decimal values among with their corresponding binary representation.</para> + </listitem> + + <listitem> + <para>Perform the following additions on binary level:</para> + + <itemizedlist> + <listitem> + <para>1 + 2</para> + </listitem> + + <listitem> + <para>-4 + 2</para> + </listitem> + + <listitem> + <para>-1 - 2</para> + </listitem> + + <listitem> + <para>3 + 1</para> + </listitem> + </itemizedlist> + </listitem> + </orderedlist> + </question> + + <answer> + <orderedlist> + <listitem> + <programlisting language="none"> 3 011 + 2 010 + 1 001 + 0 000 +-1 111 +-2 110 +-3 101 +-4 100</programlisting> + </listitem> + + <listitem> + <glosslist> + <glossentry> + <glossterm>1 + 2</glossterm> + + <glossdef> + <para><screen> 1 001 + 2 +010 +-- ---- + 3 011</screen></para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>-4 + 1</glossterm> + + <glossdef> + <screen>-4 100 + 2 +010 +-- ---- +-2 110</screen> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>-1 - 2</glossterm> + + <glossdef> + <screen>-1 111 +-2 +110 +-- ------ +-3 1_101 (See comment below)</screen> + + <para>In 3-bit two complement representation the leftmost bit will be discarded. Thus the actual result is <code>101</code> as being expected.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>3 + 1</glossterm> + + <glossdef> + <screen> 1 001 + 3 +011 +-- ---- +-4 100 Surprise! See comment below</screen> + + <para>This is actually an overflow: In 3-bit two complement representation the highest possible value is 3 being equal to <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:msup> + <m:mi>2</m:mi> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>-</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:msup> + + <m:mo>-</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:math> + </inlineequation>. Trying to add a value of 1 leads to disaster and in suitable circumstances may cause a US$370 <link xlink:href="https://en.wikipedia.org/wiki/Ariane_5#Notable_launches">spacecraft plummeting from the sky</link>! Excerpt from the <link xlink:href="http://sunnyday.mit.edu/accidents/Ariane5accidentreport.html">Ariane 5 flight 501 failure report</link>:</para> + + <blockquote> + <para>The internal SRI software exception was caused during execution of a data conversion from 64-bit floating point to 16-bit signed integer value. The floating point number which was converted had a value greater than what could be represented by a 16-bit signed integer.</para> + </blockquote> + </glossdef> + </glossentry> + </glosslist> + </listitem> + </orderedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + <qandaset defaultlabel="qanda" xml:id="sw1QandaMaxMinInt"> <title>An <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code>'s minimum and maximum value</title> <qandadiv> <qandaentry> <question> - <para>In this exercise we look at an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code>'s the largest and smallest possible value.</para> + <para>In this exercise we look at an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code>'s the largest and smallest (negative) possible value.</para> <para>A <xref linkend="glo_Java"/> <code xlink:href="https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html">int</code> is internally being represented by 4 <link linkend="glo_byte">bytes</link>. <inlineequation> <m:math display="inline"> @@ -1022,7 +1190,7 @@ int i = (int) d; // Explicit cast double to int</programlisting> </m:math> </inlineequation> for example represents the decimal value 5.</para> - <para>In order to represent negative values as well <xref linkend="glo_Java"/> uses <link xlink:href="https://en.wikipedia.org/wiki/Two's_complement#firstHeading">Two's complement</link> representation. We provide some values:</para> + <para><xref linkend="glo_Java"/> implements negative values using <link xlink:href="https://en.wikipedia.org/wiki/Two's_complement#firstHeading">Two's complement</link> representation. We provide some values:</para> <table border="1" xml:id="sw1Table4ByteIntegerRepresentation"> <caption>4 Byte <link xlink:href="https://en.wikipedia.org/wiki/Two's_complement#firstHeading">Two's complement</link> representation of <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> values.</caption> @@ -1124,11 +1292,10 @@ int i = (int) d; // Explicit cast double to int</programlisting> xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html">Integer</classname> classes. You may want to execute:</para> <programlisting language="java"> System.out.println("int minimum:" + Integer.MIN_VALUE); - System.out.println("int minimum:" + Integer.MAX_VALUE); + System.out.println("int maximum:" + Integer.MAX_VALUE); System.out.println("int bytes:" + Integer.BYTES); - System.out.println("int size:" + Integer.SIZE); -</programlisting> + System.out.println("int size:" + Integer.SIZE);</programlisting> </answer> </qandaentry> </qandadiv> @@ -1206,6 +1373,78 @@ Octal 35</screen></td> </informaltable> </figure> + <qandaset defaultlabel="qanda" xml:id="sw1QandaWild"> + <title>Pretty may not be pretty</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following program:</para> + + <programlisting language="java"> public static void main(String[] args) { + + int a = 20, + b = 3, + c = 9; + + System.out.println(a + " + " + b + " + " + c + " = " + (a + b + c)); + + }</programlisting> + + <para>This will run smoothly producing the expected output:</para> + + <screen>20 + 3 + 9 = 32</screen> + + <para>We now prettify our variable definitions by introducing right aligning numbers thereby padding leading positions with zeros:</para> + + <programlisting language="java"> public static void main(String[] args) { + + int a = 20, + b = 03, + <emphasis role="bold">c = 09; // Compiler error: The literal 09 of type int is out of range</emphasis> + + System.out.println(a + " + " + b + " + " + c + " = " + (a + b + c)); + }</programlisting> + + <para>The above code does not compile due to the compiler error when defining variable <code>c</code>.</para> + + <para>Explain the underlying cause. In particular: Why is <code>b = 03</code> just fine in contrast to <code>c = 09</code> ?</para> + + <tip> + <para>Re-read the section on integer literal representations.</para> + </tip> + </question> + + <answer> + <para>Integer literals starting with <quote>0</quote> are being interpreted as octal representation. Since the octal system's set of digits is {0,1,2,3,4,5,6,7} the value <quote>09</quote> is simply not valid.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sd1OctalOutput"> + <title>Strange output</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following code:</para> + + <programlisting language="java">int a = 041; +System.out.println("Value = " + a);</programlisting> + + <para>On execution we receive the output <code>Value = 33</code>. Explain this result</para> + </question> + + <answer> + <para>This problem is related to the previous exercise: The integer literal 041 defines octal representation. Changing from octal to decimal representation takes us to 4 * 8 + 1 = 33.</para> + + <para>There are 11 types of people: Those, who know can read binary codes, those who know what binary is and those who don't have a clue what binary is.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + <figure xml:id="sd1_fig_intLiteralLimitExcess"> <title>Know your limits!</title> @@ -1279,7 +1518,7 @@ System.out.println(10000000000 ); // Compile time error: Integer number too lar <qandadiv> <qandaentry> <question> - <para>We want to construct a list of <link xlink:href="http://www.rapidtables.com/code/text/ascii-table.htm#print">printable ASCII characters</link>. Write a <xref linkend="glo_Java"/> application by starting just from from character literals <code>' '</code>, <code>'!'</code>, <code>'"'</code>, <code>'#'</code> and so on to show their corresponding decimal values. The intended output is:</para> + <para>We want to construct a list of <link xlink:href="http://www.rapidtables.com/code/text/ascii-table.htm#print">printable ASCII characters</link>. Write a <xref linkend="glo_Java"/> application by starting just from from the character literals <code>' '</code>, <code>'!'</code>, <code>'"'</code>, <code>'#'</code>, '$', '%', '&' to show their corresponding <xref linkend="glo_ASCII"/> decimal values. The intended output is:</para> <screen> : 32 !: 33 @@ -1292,7 +1531,7 @@ $: 36 <para>Notice the empty space being represented by decimal 32.</para> <tip> - <para>A <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-E">char</code> value being represented by two bytes may be easily assigned to an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> variable.</para> + <para>A <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-E">char</code> value being represented by two bytes may be assigned to an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> variable.</para> </tip> </question> @@ -1720,6 +1959,114 @@ System.out.println("Decimal:" +<co linkends="sd1ListingPlusOpDuplicate-1" xml:id </qandadiv> </qandaset> + <qandaset defaultlabel="qanda" xml:id="sw1QandaStringVariableMix"> + <title>Composing strings of literals and variables</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following code:</para> + + <programlisting language="java">public static void main(String[] args) { + final int games = 3, playersPerGame = 22; + + // ToDo ... +}</programlisting> + + <para>Complete the above snippet by adding code to produce the following output:</para> + + <screen>3 Games having 22 players each results in 66 players altogether.</screen> + + <para>Write your code in a way that changing i.e. <code>final int games = 4</code> will result in a corresponding change of output.</para> + </question> + + <answer> + <programlisting language="java">public static void main(String[] args) { + final int games = 3, playersPerGame = 22; + + System.out.println(games + " Games having " + playersPerGame + + " players each results in " + games * playersPerGame + + " players altogether."); +}</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sw1QandaStringEscapeDoubleQuote"> + <title>Escaping double quotes</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider the following code:</para> + + <programlisting language="java">public static void main(String[] args) { + System.out.println("Some 'special' words."); +}</programlisting> + + <para>The corresponding output will be <computeroutput>Some 'special' words.</computeroutput>. Change the above code to replace the single quotes by double quotes producing the output <computeroutput>Some "special" words.</computeroutput> instead.</para> + + <tip> + <para>Hunt for <quote>java escape double quote</quote> and read about <link xlink:href="https://proquest.safaribooksonline.com/book/programming/java/9780992133047/chapter-2-language-fundamentals/toc6_html_2#readertoolbar2">character literals</link>.</para> + </tip> + </question> + + <answer> + <para>There are at least two solutions on offer:</para> + + <glosslist> + <glossentry> + <glossterm>Perfectly obvious</glossterm> + + <glossdef> + <para>Inside a string literal the string terminating character (") may be escaped using backslashes:</para> + + <programlisting language="java">System.out.println("Some \"special\" words.");</programlisting> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Even more clumsy</glossterm> + + <glossdef> + <para>Double quotes may be also represented by their char (not string!) literal:</para> + + <programlisting language="java">System.out.println("Some " + '"' + "special" + '"' + " words.");</programlisting> + </glossdef> + </glossentry> + </glosslist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sw1QandaStringSuppExercise"> + <title>Supplementary string exercises</title> + + <qandadiv> + <qandaentry> + <question> + <para xml:id="sw1QandaStringCodingBatExtra">Solve the following external exercises:</para> + + <itemizedlist> + <listitem> + <para xlink:href="http://codingbat.com/prob/p171896">helloName</para> + </listitem> + + <listitem> + <para xlink:href="http://codingbat.com/prob/p161056">makeAbba</para> + </listitem> + + <listitem> + <para xlink:href="http://codingbat.com/prob/p147483">makeTags</para> + </listitem> + </itemizedlist> + </question> + </qandaentry> + </qandadiv> + </qandaset> + <qandaset defaultlabel="qanda" xml:id="sd1_qanda_exerciseEmoticons"> <title><xref linkend="glo_unicode"/> and emoticons</title> @@ -1820,11 +2167,13 @@ System.out.println("Sum = " + sum);</programlisting> <td><screen> 01111111_11111111_11111111_11111111 + 01111111_11111111_11111111_11111111 _____________________________________ - 11111111_11111111_11111111_11111110</screen></td> +1_11111111_11111111_11111111_11111110</screen></td> </tr> </informaltable> </figure> + <para>This exceeds the four byte limit of int variables. Thus the leading <quote>1</quote> will be discarded leaving us with a result of <code>11111111_11111111_11111111_11111110</code> equalling -2 with respect to four byte integer two complement representation.</para> + <para>Why not using float / double in favour of bounded <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-A">byte</code>, <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-B">short</code>, <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code>, <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> for arithmetics?</para> <figure xml:id="sd1_fig_floatPrecision"> @@ -1958,7 +2307,35 @@ System.out.println(b);</programlisting> <answer> <para>A four byte <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> representation of 139 reads <code>00000000_00000000_00000000_10001011</code>. The cast <code>b = (byte) i</code> will strip the leading three bytes leaving <code>b</code> containing <code>10001011</code>.</para> - <para>Since byte values in <xref linkend="glo_Java"/> are being represented as signed values using two-complement notation the result is -117.</para> + <para>Since byte values in <xref linkend="glo_Java"/> are being represented as signed values using two-complement notation this equals decimal -117.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sd1_qanda_ArianeErrorMimic"> + <title><code>Ariane, I miss you!</code></title> + + <qandadiv> + <qandaentry> + <question> + <para>Reconsidering the <link xlink:href="https://www.youtube.com/watch?v=PK_yguLapgA&t=111">Ariane 5 maiden flight crash</link> read the comment buried in the solution of <xref linkend="sw1QandaTinyIntRepresent"/>. Try to mimic a code portion in <xref linkend="glo_Java"/> showing the catastrophic error.</para> + + <para>Start with a <code>double</code> variable using a value being suitable to be assigned to a <code>short</code> variable using a cast (narrowing).</para> + + <para>Then in a second step raise this value breaking your short variable's upper limit.</para> + </question> + + <answer> + <para>We start from:</para> + + <programlisting language="java">double level = 2331.12; // smaller than 32767 == Short.MAX_VALUE + +short value = (short) level; + +System.out.println(value);</programlisting> + + <para>Execution yields an expected integer output of <computeroutput>2331</computeroutput>. However increasing our <code>level</code> variable's value from 2331.12 to 42331.12 yields an output of <computeroutput>-23205</computeroutput> due to an overflow.</para> </answer> </qandaentry> </qandadiv> @@ -2074,7 +2451,7 @@ System.out.println(b);</programlisting> <td align="right">0</td> - <td align="center">...</td> + <td align="right"/> </tr> <tr> @@ -2281,98 +2658,96 @@ Process finished with exit code 1</screen> <para>Explain the underlying problem and correct Joe's error.</para> <tip> - <para>It may be helpful thinking of a smaller example before. Consider hypothetic integer types <quote>TinyLong</quote> and <quote>TinyInt</quote> requiring four and two bits respectively.</para> - </tip> - </question> + <para>It may be helpful thinking of a smaller example before. Consider two hypothetic signed integer types <quote>TinyLong</quote> and <quote>TinyInt</quote> of four and two bits respectively. The corresponding mapping will be:</para> - <answer> - <para>As a prerequisite we represent the scaling of a hypothetic integer type <quote>TinyLong</quote> of four bits to a smaller type <quote>TinyInt</quote> of two bits:</para> - - <informaltable border="1"> - <colgroup width="20%"/> + <informaltable border="1"> + <colgroup width="20%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <colgroup width="5%"/> + <colgroup width="5%"/> - <tr> - <td><quote>TinyLong</quote>, n = 4</td> + <tr> + <td><quote>TinyLong</quote>, n = 4</td> - <td>-8</td> + <td>-8</td> - <td>-7</td> + <td>-7</td> - <td>-6</td> + <td>-6</td> - <td>-5</td> + <td>-5</td> - <td>-4</td> + <td>-4</td> - <td>-3</td> + <td>-3</td> - <td>-2</td> + <td>-2</td> - <td>-1</td> + <td>-1</td> - <td>0</td> + <td>0</td> - <td>1</td> + <td>1</td> - <td>2</td> + <td>2</td> - <td>3</td> + <td>3</td> - <td>4</td> + <td>4</td> - <td>5</td> + <td>5</td> - <td>6</td> + <td>6</td> - <td>7</td> - </tr> + <td>7</td> + </tr> - <tr> - <td><quote>TinyInt</quote>, n = 2</td> + <tr> + <td><quote>TinyInt</quote>, n = 2</td> - <td colspan="4">-2</td> + <td colspan="4">-2</td> - <td colspan="4">-1</td> + <td colspan="4">-1</td> - <td colspan="4">0</td> + <td colspan="4">0</td> - <td colspan="4">1</td> - </tr> - </informaltable> + <td colspan="4">1</td> + </tr> + </informaltable> + </tip> + </question> - <para>Joe's assumption for these particular values implies dividing <quote>TinyLong</quote> values by <inlineequation> + <answer> + <para>Joe's intention with respect to our toy example types implies dividing <quote>TinyLong</quote> values by <inlineequation> <m:math display="inline"> <m:msup> <m:mi>2</m:mi> @@ -2380,20 +2755,20 @@ Process finished with exit code 1</screen> <m:mi>2</m:mi> </m:msup> </m:math> - </inlineequation> (truncating). This indeed yields the desired result for non-negative values. So why does Joe encounter a division by zero runtime exception when executing <code>longValue / (2 * (Integer.MAX_VALUE + 1))</code> ?</para> + </inlineequation> (truncating). This indeed yields the desired result for non-negative values. So why does Joe encounter a division by zero runtime exception when executing <code>longValue / (2 * (Integer.MAX_VALUE + 1))</code>?</para> <para>Unfortunately Joe's implementation is seriously flawed for even two reasons:</para> <orderedlist> <listitem> - <para>The constant <code>Integer.MAX_VALUE</code> already suggests we will not be able to increase its value while staying as an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code>. The expression <code>Integer.MAX_VALUE + 1</code> will be evaluated using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> rather than <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetic thus returning <code>Integer.MIN_VALUE</code> (negative!) due to an arithmetic overflow:</para> + <para>The constant <code xlink:href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html">Integer</code>.<code xlink:href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#MAX_VALUE">MAX_VALUE</code> already suggests we will not be able to increase its value while staying as an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code>. The expression <code>Integer.MAX_VALUE + 1</code> will be evaluated using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> rather than <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetic returning:</para> <programlisting language="java"> 01111111_11111111_11111111_11111111 + 00000000_00000000_00000000_00000001 _____________________________________ 10000000_00000000_00000000_00000000</programlisting> - <para>The expression <code>2 * (Integer.MAX_VALUE + 1)</code> then gives rise to a second overflow error:</para> + <para>This is the binary representation of the unintended result <code xlink:href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html">Integer</code>.<code xlink:href="https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#MIN_VALUE">MIN_VALUE</code> due to an arithmetic overflow. The expression <code>2 * (Integer.MAX_VALUE + 1)</code> then gives rise to a second overflow error:</para> <programlisting language="java"> 10000000_00000000_00000000_00000000 + 10000000_00000000_00000000_00000000 @@ -2402,14 +2777,14 @@ _____________________________________ </listitem> </orderedlist> - <para>Both errors combined (surprisingly) result in a value of <code>0</code> explaining the <quote>division by zero</quote> error message. There are two possible solutions:</para> + <para>Both errors combined surprisingly result in a value of <code>0</code> explaining the <quote>division by zero</quote> error message. There are two possible solutions:</para> <glosslist> <glossentry> <glossterm><code>(int) (longValue / (2L * (Integer.MAX_VALUE + 1L)))</code></glossterm> <glossdef> - <para>Introducing <code>2L</code> or <code>1L</code> (one is sufficient) in favour of simply using 2 and 1 turns both addition and multiplication into operations involving at least one long argument. Thus for both operations the <xref linkend="glo_Java"/> runtime will use <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetic returning the desired <quote>reducing</quote> factor of <inlineequation> + <para>Introducing <code>2L</code> or <code>1L</code> (one is sufficient) in favour of simply using 2 and 1 turns both addition and multiplication into operations involving at least one <code>long</code> argument. Thus for both operations the <xref linkend="glo_Java"/> runtime will use <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetic returning the desired <quote>reducing</quote> factor of <inlineequation> <m:math display="inline"> <m:msup> <m:mi>2</m:mi> @@ -2428,7 +2803,7 @@ _____________________________________ <para>Same result as before.</para> <note> - <para>This time the expression starts with <code>longValue / 2 ...</code> Since the variable <code>longValue</code> is of type <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> the expression <code>longValue / 2</code> will be evaluated by the <xref linkend="glo_Java"/> runtime using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetics. The result will subsequently be multiplied with <code>Integer.MAX_VALUE + 1L</code> again using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetic.</para> + <para>This time the expression starts with <code>longValue / 2 ...</code> Since the variable <code>longValue</code> is of type <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> the expression <code>longValue / 2</code> will be evaluated by the <xref linkend="glo_Java"/> runtime using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetics. The result will subsequently be divided by <code>Integer.MAX_VALUE + 1L</code> again using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-D">long</code> arithmetic.</para> </note> </glossdef> </glossentry> @@ -2523,6 +2898,104 @@ short sum = a + 7; <co linkends="sd1_co_expressionTypeIntToShort-2" xml:id="sd1_ </qandadiv> </qandaset> + <qandaset defaultlabel="qanda" xml:id="sw1QandaByteOverflow"> + <title>Strange things happen</title> + + <qandadiv> + <qandaentry> + <question> + <orderedlist> + <listitem> + <para>Consider the following code snippet:</para> + + <programlisting language="java">byte a = 127; +System.out.println("Current value=" + a + ", now adding 1 to it"); +a++; +System.out.println("New value=" + a);</programlisting> + + <para>This will produce the following output:</para> + + <screen>Current value=127, now adding 1 to it +New value=-128</screen> + + <para>Explain this strange behaviour.</para> + </listitem> + + <listitem> + <para>Moreover the following yields a compile time error:</para> + + <programlisting language="java">byte a = 127; +System.out.println("value=" + a); +a = a + 1; // Error: Type mismatch: cannot convert from int to byte +System.out.println("New value=" + a);</programlisting> + + <para>What do you learn about the two operators <quote><code>+</code></quote> an <quote><code>a++</code></quote>? Explain this error's cause.</para> + </listitem> + </orderedlist> + + <tip> + <para>You may want to read the <link xlink:href="https://proquest.safaribooksonline.com/9780992133047/toc1_html_4">overview section</link> on statements.</para> + </tip> + </question> + + <answer> + <orderedlist> + <listitem> + <para>A byte variable ranges from -128 to +127. Thus incrementing 127 by 1 yields -128 and thus an overflow error.</para> + + <para>Since <xref linkend="glo_Java"/> uses <link xlink:href="https://en.wikipedia.org/wiki/Two's_complement#firstHeading">Two's complement</link> representation we have:</para> + + <informaltable border="1"> + <tr> + <td><code> 01111111</code></td> + + <td><code> 127</code></td> + </tr> + + <tr> + <td><code>+00000001</code></td> + + <td><code> +1</code></td> + </tr> + + <tr> + <td><code>=10000000</code></td> + + <td><code>=-128</code></td> + </tr> + </informaltable> + + <para>On machine level the above calculation is just an ordinary addition.</para> + + <para>Conclusion: Watch out when doing (integer) arithmetic!</para> + </listitem> + + <listitem> + <para>The compile time error is due to the definition of the <quote>+</quote> operator in Java always returning an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> rather than a byte. Consider:</para> + + <programlisting language="java">byte a = 120, b = 10; +System.out.println(a + b);</programlisting> + + <para>This yields the expected output of 130 and corresponds to an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> value.</para> + + <para>If the expression <code>a + b</code> was of data type <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-A">byte</code> in <xref linkend="glo_Java"/> an arithmetic overflow as in the subsequent code example would occur:</para> + + <programlisting language="java">byte a = 120, b = 10; + +byte sum = (byte) (a + b); + +System.out.println(sum);</programlisting> + + <para>The explicit type conversion (a so called <quote>type cast</quote> or cast for short) forces the 4-byte <code>int</code> into a one-byte variable <code>sum</code> thereby loosing its original value and returning -126 instead.</para> + + <para>Conclusion: <code>a = a + 1</code> and <code>a++</code> differ in behaviour when being applied to non-<code>int</code> variables.</para> + </listitem> + </orderedlist> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + <qandaset defaultlabel="qanda" xml:id="sd1_qanda_integerSumOverflow"> <title>Adding values</title> @@ -2567,6 +3040,78 @@ System.out.println(2147483647 + 1L);</programlisting> </qandadiv> </qandaset> + <qandaset defaultlabel="qanda" xml:id="sd1QandaFloatPrecisionProblem"> + <title>Representational float and double miracles</title> + + <qandadiv> + <qandaentry> + <question> + <para>Consider and execute the following code snippet:</para> + + <programlisting language="java">public static void main(String[] args) { + final double a = 0.7; + final double b = 0.9; + final double x = a + 0.1; // 0.9 + final double y = b - 0.1; // 0.9 + System.out.println(x == y); +}</programlisting> + + <para>Which outcome do you expect? Explain the execution's result and propose a solution.</para> + + <tip> + <para>You will have to replace the <quote>==</quote> operator by something more appropriate addressing limited arithmetic precision.</para> + </tip> + </question> + + <answer> + <para>The expression <code>x == y</code> evaluates to <code>false</code>. This surprising result is due to limited precision regarding both <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">float</code> and <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">double</code> IEEE representations: A given value will be approximated as close as possible.</para> + + <para>Adding <code>System.out.println(x - y)</code> yields a value of -1.1102230246251565E-16 denoting the representational deviation of <code>x</code> and <code>y</code>.</para> + + <para>Comparing <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">float</code> and <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">double</code> values thus requires providing a representational distance limit below which two values will be regarded as equal:</para> + + <programlisting language="java">final double a = 0.7; +final double b = 0.9; +final double x = a + 0.1; +final double y = b - 0.1; +System.out.println(<link xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#abs-double-">Math.abs</link>(x - y) < 1.E-14);</programlisting> + + <para>The last line represents the boolean expression <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>|</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>-</m:mo> + + <m:mi>y</m:mi> + </m:mrow> + + <m:mo>|</m:mo> + </m:mrow> + + <m:mo><</m:mo> + + <m:msup> + <m:mi>10</m:mi> + + <m:mrow> + <m:mo>-</m:mo> + + <m:mi>14</m:mi> + </m:mrow> + </m:msup> + </m:mrow> + </m:math> + </inlineequation>. So two values will be regarded as equal if their mutual distance is less than 0.00000000000001.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + <figure xml:id="sd1_fig_genericBinaryOpType"> <title>Generic type behaviour</title> @@ -2654,7 +3199,7 @@ System.out.println(2147483647 + 1L);</programlisting> </figure> <qandaset defaultlabel="qanda" xml:id="sw1QandaCircleArea"> - <title>Calculating a circle area</title> + <title>Calculating a circle's area</title> <qandadiv> <qandaentry> @@ -2743,6 +3288,147 @@ System.out.println(2147483647 + 1L);</programlisting> </qandadiv> </qandaset> + <qandaset defaultlabel="qanda" xml:id="sw1QandaCircleAreaFinal"> + <title>Calculating the area of a circle avoiding accidental redefinition</title> + + <qandadiv> + <qandaentry> + <question> + <para>In Exercise <xref linkend="sw1QandaCircleArea"/> you calculated a given circle's area:</para> + + <programlisting language="java"> public static void main(String[] args) { + + double radius = 2.31; // A circle having a radius (given e.g. in mm). + double pi = 3.1415926; // Constant relating a circle's radius, perimeter + //and area. + + double area = pi * radius * radius; + System.out.println(area); + }</programlisting> + + <para>Though there is nothing wrong with this approach it is error prone: In a similar program a careless programmer accidentally redefine the value of <code>pi</code>:</para> + + <programlisting language="java">double pi = 3.141592653589793; + +double radius = 2.3; // Computing a circle's area +System.out.println("A circle of radius " + radius + " will cover an area of " + + pi * radius * radius); + +pi = -4; // Woops, accidential redefinition + +radius = 1.8; + +System.out.println("A circle of radius " + radius + " will cover an area of " + + pi * radius * radius);</programlisting> + + <para>Modify the above code to avoid this type of error.</para> + + <tip> + <itemizedlist> + <listitem> + <para>Consider <xref linkend="sd1_fig_final"/>.</para> + </listitem> + + <listitem> + <para>Read the <quote xlink:href="https://proquest.safaribooksonline.com/9780992133047/toc5_html_2">Constants</quote> section of <xref linkend="bib_Kurniawan2015"/>. As an aside also read the nearby section concerning naming conventions for constant variable as well.</para> + </listitem> + </itemizedlist> + </tip> + </question> + + <answer> + <para>The solution is straightforward. We add the <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> modifier to the definition of our variable <code>pi</code>. In addition we use capital letters <code>PI</code> reflecting the naming convention for constants:</para> + + <programlisting language="java" linenumbering="numbered">final double PI = 3.141592653589793; +double radius = 2.3; // Computing a circle's area +System.out.println("A circle of radius " + radius + " will cover an area of " + + PI * radius * radius); + +PI = -4; + +radius = 1.8; + +System.out.println("A circle of radius " + radius + " will cover an area of " + + PI * radius * radius);</programlisting> + + <para>Now our flawed assignment at line 6 will be flagged as a compile time error:</para> + + <para><computeroutput>Cannot assign a value to final variable 'PI'</computeroutput></para> + + <para>As a rule of thumb: Whenever you intend a variable not to change after an initial assignment use <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> declaring it to remain constant.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <qandaset defaultlabel="qanda" xml:id="sw1QandaCircleMathDotPI"> + <title>Using predefined constants</title> + + <qandadiv> + <qandaentry> + <question> + <para>In the previous exercise we coded:</para> + + <programlisting language="java" linenumbering="numbered">final double PI = 3.141592653589793; +double radius = 2.3; // Computing a circle's area +System.out.println("A circle of radius " + radius + " will cover an area of " + + PI * radius * radius);</programlisting> + + <para>Do we actually have to provide the value of pi (3.141592653589793) ourself?</para> + + <programlisting language="java">double pi = 3.141592653589793; + +double radius = 2.3; // Computing a circle's area +System.out.println("A circle of radius " + radius + " will cover an area of " + + pi * radius * radius); + +pi = -4; // Woops, accidential redefinition + +radius = 1.8; + +System.out.println("A circle of radius " + radius + " will cover an area of " + + pi * radius * radius);</programlisting> + + <para>Modify the above code to avoid this type of error.</para> + + <tip> + <itemizedlist> + <listitem> + <para>Consider <xref linkend="sd1_fig_final"/>.</para> + </listitem> + + <listitem> + <para>Read the <quote xlink:href="https://proquest.safaribooksonline.com/9780992133047/toc5_html_2">Constants</quote> section of <xref linkend="bib_Kurniawan2015"/>. As an aside also read the nearby section concerning naming conventions for constant variable as well.</para> + </listitem> + </itemizedlist> + </tip> + </question> + + <answer> + <para>The solution is straightforward. We add the <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> modifier to the definition of our variable <code>pi</code>. In addition we use capital letters <code>PI</code> reflecting the naming convention for constants:</para> + + <programlisting language="java" linenumbering="numbered">final double PI = 3.141592653589793; +double radius = 2.3; // Computing a circle's area +System.out.println("A circle of radius " + radius + " will cover an area of " + + PI * radius * radius); + +PI = -4; + +radius = 1.8; + +System.out.println("A circle of radius " + radius + " will cover an area of " + + PI * radius * radius);</programlisting> + + <para>Now our flawed assignment at line 6 will be flagged as a compile time error:</para> + + <para><computeroutput>Cannot assign a value to final variable 'PI'</computeroutput></para> + + <para>As a rule of thumb: Whenever you intend a variable not to change after an initial assignment use <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> declaring it to remain constant.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + <qandaset defaultlabel="qanda" xml:id="sd1QandaTemperatureConvert"> <title>Converting temperature values</title> @@ -3238,441 +3924,4 @@ System.out.println("a = " + a + ", b = " + b + ", c = " + c);</programlisting> </qandaset> </section> </section> - - <section xml:id="sd1_sect_langFundamental_exercises"> - <title>Exercises</title> - - <section xml:id="sw1SectSimpleExpressions"> - <title>Simple expressions</title> - - <qandaset defaultlabel="qanda" xml:id="sd1QandaFloatPrecisionProblem"> - <title>Representational float and double miracles</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider and execute the following code snippet:</para> - - <programlisting language="java">public static void main(String[] args) { - final double a = 0.7; - final double b = 0.9; - final double x = a + 0.1; // 0.9 - final double y = b - 0.1; // 0.9 - System.out.println(x == y); -}</programlisting> - - <para>Which outcome do you expect? Explain the execution's result and propose a solution.</para> - - <tip> - <para>You will have to replace the <quote>==</quote> operator by something more appropriate addressing limited arithmetic precision.</para> - </tip> - </question> - - <answer> - <para>The expression <code>x == y</code> evaluates to <code>false</code>. This surprising result is due to limited precision regarding both <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">float</code> and <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">double</code> IEEE representations: A given value will be approximated as close as possible.</para> - - <para>Adding <code>System.out.println(x - y)</code> yields a value of -1.1102230246251565E-16 denoting the representational deviation of <code>x</code> and <code>y</code>.</para> - - <para>Comparing <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">float</code> and <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3-100">double</code> values thus requires providing a representational distance limit below which two values will be regarded as equal:</para> - - <programlisting language="java">final double a = 0.7; -final double b = 0.9; -final double x = a + 0.1; -final double y = b - 0.1; -System.out.println(<link xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#abs-double-">Math.abs</link>(x - y) < 1.E-14);</programlisting> - - <para>The last line represents the boolean expression <inlineequation> - <m:math display="inline"> - <m:mrow> - <m:mrow> - <m:mo>|</m:mo> - - <m:mrow> - <m:mi>x</m:mi> - - <m:mo>-</m:mo> - - <m:mi>y</m:mi> - </m:mrow> - - <m:mo>|</m:mo> - </m:mrow> - - <m:mo><</m:mo> - - <m:msup> - <m:mi>10</m:mi> - - <m:mrow> - <m:mo>-</m:mo> - - <m:mi>14</m:mi> - </m:mrow> - </m:msup> - </m:mrow> - </m:math> - </inlineequation>. So two values will be regarded as equal if their mutual distance is less than </para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sw1QandaByteOverflow"> - <title>Strange things happen</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following code snippet:</para> - - <programlisting language="java">byte a = 127; -System.out.println("value=" + a); -a++; -System.out.println("New value=" + a);</programlisting> - - <para>This will produce the following output:</para> - - <screen>value=127 -New value=-128</screen> - - <para>Explain this strange behaviour.</para> - - <para>Moreover you'll find the following code snippet yields a compile time error:</para> - - <programlisting language="java">byte a = 127; -System.out.println("value=" + a); -a = a + 1; // Error: Type mismatch: cannot convert from int to byte -System.out.println("New value=" + a);</programlisting> - - <para>Explain this error's cause.</para> - - <tip> - <para>You may want to read the <link xlink:href="https://proquest.safaribooksonline.com/9780992133047/toc1_html_4">overview section</link> on statements.</para> - </tip> - </question> - - <answer> - <para>A byte variable ranges from -128 to +127. Thus incrementing 127 by 1 yields -128 and thus an overflow error.</para> - - <para>Since <xref linkend="glo_Java"/> uses <link xlink:href="https://en.wikipedia.org/wiki/Two's_complement#firstHeading">Two's complement</link> representation we have:</para> - - <informaltable border="1"> - <tr> - <td><code> 01111111</code></td> - - <td><code> 127</code></td> - </tr> - - <tr> - <td><code>+00000001</code></td> - - <td><code> +1</code></td> - </tr> - - <tr> - <td><code>=10000000</code></td> - - <td><code>=-128</code></td> - </tr> - </informaltable> - - <para>On machine level the above calculation is just an ordinary addition.</para> - - <para>Conclusion: Watch out when doing (integer) arithmetic!</para> - - <para>The compile time error is due to the definition of the <quote>+</quote> operator in Java always returning an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> rather than a byte. Consider:</para> - - <programlisting language="java"> byte a = 120, b = 10; - System.out.println(a + b);</programlisting> - - <para>This yields the expected output of 130 and corresponds to an <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-C">int</code> value.</para> - - <para>If the expression <code>a + b</code> was of data type <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1-100-A">byte</code> an arithmetic overflow as in the subsequent code example would occur:</para> - - <programlisting language="java"> byte a = 120, b = 10; - - byte sum = (byte) (a + b); - - System.out.println(sum);</programlisting> - - <para>The explicit type conversion (a so called type cast or cast for short) forces the 4-byte integer into a one-byte variable <code>sum</code> thereby loosing the original value and returning -126 instead.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sw1StringLiterals"> - <title>Dealing with strings</title> - - <qandaset defaultlabel="qanda" xml:id="sw1QandaStringVariableMix"> - <title>Composing strings of literals and variables</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following code:</para> - - <programlisting language="java"> public static void main(String[] args) { - final int games = 3, playersPerGame = 22; - - // ToDo ... - - }</programlisting> - - <para>Complete the above snippet by adding code to produce the following output:</para> - - <screen>3 Games having 22 players each results in 66 players altogether.</screen> - - <para>Write your code in a way that changing i.e. <code>final int games = 4</code> will result in a corresponding change of output.</para> - </question> - - <answer> - <programlisting language="java"> public static void main(String[] args) { - final int games = 3, playersPerGame = 22; - - System.out.println(games + " Games having " + playersPerGame - + " players each results in " + games * playersPerGame - + " players altogether."); - - }</programlisting> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sw1QandaStringEscapeDoubleQuote"> - <title>Escaping double quotes</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following code:</para> - - <programlisting language="java">public static void main(String[] args) { - System.out.println("Some 'special' words."); -}</programlisting> - - <para>The corresponding output will be <computeroutput>Some 'special' words.</computeroutput>. Change the above code to replace the single quotes by double quotes producing the output <computeroutput>Some "special" words.</computeroutput> instead.</para> - - <tip> - <para>Hunt for <quote>java escape double quote</quote> and read about <link xlink:href="https://proquest.safaribooksonline.com/book/programming/java/9780992133047/chapter-2-language-fundamentals/toc6_html_2#readertoolbar2">character literals</link>.</para> - </tip> - </question> - - <answer> - <para>There are at least two solutions on offer:</para> - - <glosslist> - <glossentry> - <glossterm>Perfectly obvious</glossterm> - - <glossdef> - <para>Inside a string literal the string terminating character (") may be escaped using backslashes:</para> - - <programlisting language="java">System.out.println("Some \"special\" words.");</programlisting> - </glossdef> - </glossentry> - - <glossentry> - <glossterm>Even more clumsy</glossterm> - - <glossdef> - <para>Double quotes may be also represented by their char (not string!) literal:</para> - - <programlisting language="java">System.out.println("Some " + '"' + "special" + '"' + " words.");</programlisting> - </glossdef> - </glossentry> - </glosslist> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sw1QandaStringSuppExercise"> - <title>Supplementary string exercises</title> - - <qandadiv> - <qandaentry> - <question> - <para xml:id="sw1QandaStringCodingBatExtra">Solve the following external exercises:</para> - - <itemizedlist> - <listitem> - <para xlink:href="http://codingbat.com/prob/p171896">helloName</para> - </listitem> - - <listitem> - <para xlink:href="http://codingbat.com/prob/p161056">makeAbba</para> - </listitem> - - <listitem> - <para xlink:href="http://codingbat.com/prob/p147483">makeTags</para> - </listitem> - </itemizedlist> - </question> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sw1LanguageFundamentalUsingFinal"> - <title>Using <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code></title> - - <qandaset defaultlabel="qanda" xml:id="sw1QandaCircleAreaFinal"> - <title>Calculating the area of a circle avoiding accidental redefinition</title> - - <qandadiv> - <qandaentry> - <question> - <para>In Exercise <xref linkend="sw1QandaCircleArea"/> you calculated a given circle's area:</para> - - <programlisting language="java"> public static void main(String[] args) { - - double radius = 2.31; // A circle having a radius (given e.g. in mm). - double pi = 3.1415926; // Constant relating a circle's radius, perimeter - //and area. - - double area = pi * radius * radius; - System.out.println(area); - }</programlisting> - - <para>Though there is nothing wrong with this approach it actually is error prone: A careless programmer may accidentally redefine the value of <code>pi</code>:</para> - - <programlisting language="java"> public static void main(String[] args) { - - double radius = 2.31; // A circle having a radius (given e.g. in mm). - double pi = 3.1415926; // Constant relating a circle's radius, perimeter - //and area. - - // Some lines of code in between - // ... - - pi = -17; // Woops! This shall not happen! - - // More lines of code - // ... - - double area = pi * radius * radius; - System.out.println(area); - }</programlisting> - - <para>Modify the original code to avoid this type of error.</para> - - <tip> - <para>You may want to read the <quote xlink:href="https://proquest.safaribooksonline.com/9780992133047/toc5_html_2">Constants</quote> section of <xref linkend="bib_Kurniawan2015"/>.</para> - </tip> - </question> - - <answer> - <para>The solution is straightforward. We add the <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> modifier to the definition of our variable <code>pi</code>:</para> - - <programlisting language="java" linenumbering="numbered">public static void main(String[] args) { - - double radius = 2.31; // A circle's radius (given e.g. in mm). - <emphasis role="bold">final</emphasis> double pi = 3.1415926; // Creating pi as a constant (non-modifiable/ - // assignable) variable. - - // Longer code section in between - // ... - - pi = -17; // Compile time error. - - // Another longer code section - // ... - - <emphasis role="bold">final</emphasis> double area = pi * radius * radius; - System.out.println(area); -}</programlisting> - - <para>Now our flawed assignment at line 9 will be flagged as a compile time error:</para> - - <para><computeroutput>The final local variable pi cannot be assigned. It must be blank and not using a compound assignment</computeroutput></para> - - <para>Note the second <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> modification in the definition of our variable <code>area</code> to avoid erroneous redefinitions as well.</para> - - <para>As a rule of thumb: Whenever you intend a variable not to change after an initial assignment use <code xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4">final</code> declaring it to remain constant.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - - <section xml:id="sd1fundamentalsWildThings"> - <title>Wild things</title> - - <qandaset defaultlabel="qanda" xml:id="sw1QandaWild"> - <qandadiv> - <qandaentry> - <question> - <para>Consider the following program:</para> - - <programlisting language="java"> public static void main(String[] args) { - - int a = 20, - b = 3, - c = 9; - - System.out.println(a + " + " + b + " + " + c + " = " + (a + b + c)); - - }</programlisting> - - <para>This will run smoothly producing the expected output:</para> - - <screen>20 + 3 + 9 = 32</screen> - - <para>We now prettify our variable definitions by introducing right aligning numbers thereby padding leading positions with zeros:</para> - - <programlisting language="java"> public static void main(String[] args) { - - int a = 20, - b = 03, - <emphasis role="bold">c = 09; // Compiler error: The literal 09 of type int is out of range</emphasis> - - System.out.println(a + " + " + b + " + " + c + " = " + (a + b + c)); - }</programlisting> - - <para>The above code does not compile due to the compiler error when defining variable <code>c</code>.</para> - - <para>Explain the underlying cause of this error message. Why is <code>b = 03</code> just fine in contrast to <code>c = 09</code> ?</para> - - <tip> - <para>Re-read the section on integer literal representations.</para> - </tip> - </question> - - <answer> - <para>Integer literals starting with <quote>0</quote> are being interpreted as octal representation. Since the octal system's set of digits is {0,1,2,3,4,5,6,7} the value <quote>09</quote> is simply not valid.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - - <qandaset defaultlabel="qanda" xml:id="sd1OctalOutput"> - <title>Strange output</title> - - <qandadiv> - <qandaentry> - <question> - <para>Consider the following code:</para> - - <programlisting language="java"> public static void main(String[] args) { - - int a = 041; - System.out.println("Value = " + a); - }</programlisting> - - <para>On execution we receive the output <code>Value = 33</code>. Explain this result</para> - </question> - - <answer> - <para>This problem is related to the previous exercise: The integer literal 041 defines octal representation. Changing from octal to decimal representation takes us to 4 * 8 + 1 = 33.</para> - - <para>There are 11 types of people: Those, who know can read binary codes, those who know what binary is and those who don't have a clue what binary is.</para> - </answer> - </qandaentry> - </qandadiv> - </qandaset> - </section> - </section> </chapter>