Skip to content
Snippets Groups Projects
Commit fd8e9579 authored by Goik Martin's avatar Goik Martin
Browse files

AutoCloseable, Exercise understanding initializations in try ... catch

parent 719c1b18
No related branches found
No related tags found
No related merge requests found
...@@ -336,7 +336,7 @@ try { ...@@ -336,7 +336,7 @@ try {
xml:id="sd1_errorHandling_fig_tryWithResources-2-co"/> = new Scanner(System.in)) { xml:id="sd1_errorHandling_fig_tryWithResources-2-co"/> = new Scanner(System.in)) {
... // Something may fail ... // Something may fail
}<co linkends="sd1_errorHandling_fig_tryWithResources-3" }<co linkends="sd1_errorHandling_fig_tryWithResources-3"
xml:id="sd1_errorHandling_fig_tryWithResources-3-co"/></programlisting> xml:id="sd1_errorHandling_fig_tryWithResources-3-co"/> // implicitly calling scanner.close()</programlisting>
<calloutlist> <calloutlist>
<callout arearefs="sd1_errorHandling_fig_tryWithResources-1-co" <callout arearefs="sd1_errorHandling_fig_tryWithResources-1-co"
...@@ -360,6 +360,56 @@ try { ...@@ -360,6 +360,56 @@ try {
</callout> </callout>
</calloutlist> </calloutlist>
</figure> </figure>
<figure xml:id="sd1_errorHandling_fig_ScannerAutoCloseable">
<title>Scanner implementing <classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/AutoCloseable.html">AutoCloseable</classname></title>
<informaltable border="0">
<tr>
<td valign="top"><programlisting language="java">public class Scanner
implements AutoCloseable <co
linkends="sd1_errorHandlingAutoCloseablePromise-1"
xml:id="sd1_errorHandlingAutoCloseablePromise-1-co"/>, ... {
...
public void close() {...} <co
linkends="sd1_errorHandlingAutoCloseablePromise-2"
xml:id="sd1_errorHandlingAutoCloseablePromise-2-co"/>
}</programlisting></td>
<td valign="top"><programlisting language="java">Interface AutoCloseable {
public void close(); // Signature, no
// implementation
}</programlisting></td>
</tr>
</informaltable>
<calloutlist>
<callout arearefs="sd1_errorHandlingAutoCloseablePromise-1-co"
xml:id="sd1_errorHandlingAutoCloseablePromise-1">
<para>Promise to implement all methods being declared in <classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/AutoCloseable.html">AutoCloseable</classname>.</para>
</callout>
<callout arearefs="sd1_errorHandlingAutoCloseablePromise-2-co"
xml:id="sd1_errorHandlingAutoCloseablePromise-2">
<para>Actually implementing a <methodname>close()</methodname>
method.</para>
</callout>
</calloutlist>
</figure>
<figure xml:id="sd1_errorHandling_fig_tryWithResourcesString">
<title>No <methodname>close()</methodname> method in e.g.
<classname>class</classname> String</title>
<programlisting language="java">try (final String s = new String()) { // Error: Required type: AutoCloseable; Provided: String
...
}</programlisting>
</figure>
</section> </section>
<section xml:id="sd1_errorhandling_sect_classException"> <section xml:id="sd1_errorhandling_sect_classException">
...@@ -437,11 +487,9 @@ public class StackTrace { ...@@ -437,11 +487,9 @@ public class StackTrace {
new <link xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/File.html#%3Cinit%3E(java.lang.String)">File("test.txt"))</link>; new <link xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/File.html#%3Cinit%3E(java.lang.String)">File("test.txt"))</link>;
} catch(Exception e) { } catch(Exception e) {
System.err.println("General error"); System.err.println("General error");
} catch (<emphasis role="red" } catch (<emphasis role="red">IOException e</emphasis>) {
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/IOException.html">IOException e</emphasis>) {
System.err.println( "IO error"); System.err.println( "IO error");
} catch(<emphasis role="red" } catch(<emphasis role="red">FileNotFoundException e</emphasis>) {
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/io/FileNotFoundException.html">FileNotFoundException e</emphasis>) {
System.err.println("File not found"); System.err.println("File not found");
}</programlisting></td> }</programlisting></td>
...@@ -457,11 +505,9 @@ public class StackTrace { ...@@ -457,11 +505,9 @@ public class StackTrace {
<figure xml:id="sd1_errorHandling_fig_implementCardinalSimple"> <figure xml:id="sd1_errorHandling_fig_implementCardinalSimple">
<title>Implementing <methodname>convert</methodname></title> <title>Implementing <methodname>convert</methodname></title>
<programlisting language="java">/** <programlisting language="java">/* Translate {"one", "two", "three"} to {"first", "second", "third"}
* Translate {"one", "two", "three"} to {"first", "second", "third"}
* @param input The input String to be translated. * @param input The input String to be translated.
* @return See above explanation. * @return See above explanation. */
*/
static public String convert(final String input) { static public String convert(final String input) {
switch (input) { switch (input) {
case "one": return "first"; case "one": return "first";
......
...@@ -324,16 +324,17 @@ Double d = intValue;</programlisting> ...@@ -324,16 +324,17 @@ Double d = intValue;</programlisting>
<colgroup width="35%"/> <colgroup width="35%"/>
<tr> <tr>
<td valign="top"><programlisting language="java">String userInput = "dummyValue"; <td valign="top"><programlisting language="java">String userInput = null;
try (final Scanner scanner = try (final Scanner scanner =
new Scanner(System.in)){ new Scanner(System.in)){
System.out.print("Enter an integer:"); System.out.print("Enter an integer:");
userInput = scanner.nextLine(); userInput = scanner.nextLine();
final int value = Integer.parseInt(userInput); final int value = Integer.parseInt(userInput);
System.out.println("You entered " + value); System.out.println("You entered " + value);
} catch (final NumberFormatException e) { } catch (final NumberFormatException e) {
System.out.println("Sorry, but '" + System.out.println("Error: No integer value");
userInput + "' is not an integer.");
}</programlisting></td> }</programlisting></td>
<td valign="top"><screen>Enter an integer:-34 <td valign="top"><screen>Enter an integer:-34
...@@ -346,14 +347,14 @@ not an integer.</screen></td> ...@@ -346,14 +347,14 @@ not an integer.</screen></td>
<qandaset defaultlabel="qanda" xml:id="sd1_numbers_qanda_whyDummyString"> <qandaset defaultlabel="qanda" xml:id="sd1_numbers_qanda_whyDummyString">
<title>Why using <code language="java">String userInput = <title>Why using <code language="java">String userInput =
"dummyValue"</code>?</title> null</code>?</title>
<qandadiv> <qandadiv>
<qandaentry> <qandaentry>
<question> <question>
<para>The former listing initializes the <code <para>The former listing initializes the <code
language="java">userInput</code> variable using a default value language="java">userInput</code> variable using a default value
<code language="java">"dummyValue"</code>. Why is that?</para> <code language="java">null</code>. Why is that?</para>
<orderedlist> <orderedlist>
<listitem> <listitem>
...@@ -379,26 +380,35 @@ not an integer.</screen></td> ...@@ -379,26 +380,35 @@ not an integer.</screen></td>
</orderedlist> </orderedlist>
<para>So the dummy assignment <code language="java">String <para>So the dummy assignment <code language="java">String
userInput = "dummyValue"</code> seems to be redundant. Is that userInput = null</code> seems to be redundant. Is that
true?</para> true?</para>
</question> </question>
<answer> <answer>
<para>Actually the <xref linkend="glo_Java"/> compiler is not <para>Actually the <xref linkend="glo_Java"/> compiler is not
clever enough analyzing the <code language="java">try {...}</code> clever enough analyzing the <code language="java">try {...}</code>
block. It cannot detect the impossibility of an uninitialized block. The catch clause can only be reached by inadequate user
<code language="java">userInput</code> variable inside the <code input causing the <methodname>parseInt(...)</methodname> method.
language="java">catch {...}</code> clause.</para> In particular the <methodname>nextLine(...)</methodname> being
unable to throw a <classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/NumberFormatException.html">NumberFormatException</classname>
cannot be the culprit for entering the <code
language="java">catch</code> clause. Thus if a <classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/NumberFormatException.html">NumberFormatException</classname>
is being thrown our <code language="java">userInput</code>
variable will already carry a user entered input string. The
compiler however cannot analyze this type of dependency.</para>
<para>Since the possibility of am uninitialized <code <para>Thus the possibility of an uninitialized <code
language="java">userInput</code> variable using just <code language="java">userInput</code> variable using just <code
language="java">String userInput;</code> causes a compile time language="java">String userInput;</code> would cause a compile
error <code>Variable 'userInput' might not have been time error <code>Variable 'userInput' might not have been
initialized</code>.</para> initialized</code>.</para>
<para>Thus <code language="java">String userInput = null</code> <para><code language="java">So userInput = null</code> is
would be appropriate as well since the value will actually never sufficient for keeping the compiler happy and inside the catch
be used.</para> clause the variable will definitively carry a<classname>
String</classname> reference.</para>
</answer> </answer>
</qandaentry> </qandaentry>
</qandadiv> </qandadiv>
...@@ -969,6 +979,25 @@ System.out.println(result);</programlisting> ...@@ -969,6 +979,25 @@ System.out.println(result);</programlisting>
<programlisting language="java">final BigDecimal zero_dot_99 = new BigDecimal("0.99"); <programlisting language="java">final BigDecimal zero_dot_99 = new BigDecimal("0.99");
final BigDecimal zero_dot_1 = new BigDecimal("0.1"); final BigDecimal zero_dot_1 = new BigDecimal("0.1");
BigDecimal
result = zero_dot_99.subtract(zero_dot_1); // Subtracting 0.1
result = result.subtract(zero_dot_1); // Subtracting 0.1
result = result.subtract(zero_dot_1); // Subtracting 0.1
System.out.println(result);</programlisting>
<screen>0.69</screen>
</figure>
<figure xml:id="sd1_numbers_fig_usingBigDecimalChaining">
<title>Chaining <classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/BigDecimal.html">BigDecimal</classname>
operations</title>
<programlisting language="java">final BigDecimal zero_dot_99 = new BigDecimal("0.99");
final BigDecimal zero_dot_1 = new BigDecimal("0.1");
BigDecimal result = zero_dot_99. BigDecimal result = zero_dot_99.
subtract(zero_dot_1). subtract(zero_dot_1).
subtract(zero_dot_1). subtract(zero_dot_1).
...@@ -979,6 +1008,46 @@ System.out.println(result);</programlisting> ...@@ -979,6 +1008,46 @@ System.out.println(result);</programlisting>
<screen>0.69</screen> <screen>0.69</screen>
</figure> </figure>
<qandaset defaultlabel="qanda"
xml:id="sd1_workingWithNumbers_BigDecimalChaining">
<title>Chaining subtract method calls</title>
<qandadiv>
<qandaentry>
<question>
<para>Explain the chaining mechanism implementing three successive
subtractions in <xref
linkend="sd1_numbers_fig_usingBigDecimalChaining"/>.</para>
</question>
<answer>
<para>We may re-write the statement in question:</para>
<programlisting language="none">result = zero_dot_99.subtract(zero_dot_1).subtract(zero_dot_1).subtract(zero_dot_1);
\ / / /
\ / / /
\ / / /
0.99 - 0.1 / /
\ / /
\ / /
\ / /
0.98 - 0.1 /
\ /
\ /
0.97 - 0.1
== 0.96</programlisting>
<para>Each <methodname>subtract(...)</methodname> call returns a
new result instance of class <classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/BigDecimal.html">BigDecimal</classname>.
We can thus chain a subsequent
<methodname>subtract(...)</methodname> call using this returned
instance.</para>
</answer>
</qandaentry>
</qandadiv>
</qandaset>
<figure xml:id="sd1_numbers_fig_usingBigDecimalFeatures"> <figure xml:id="sd1_numbers_fig_usingBigDecimalFeatures">
<title><classname <title><classname
xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/BigDecimal.html">BigDecimal</classname> xlink:href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/math/BigDecimal.html">BigDecimal</classname>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment