5
\$\begingroup\$

I have created a sample file reading program as an exercise while learning how to implement good exception handling. I want to ask: is this a good approach or is there some other solution that I am not aware of?

import java.util.*;  // Needed for Scanner and InputMismatchException
import java.io.*;    // Needed for FileReader and FileNotFoundException

/**
 * This class reads two numbers from a file and 
 * print their sum.  
 */

public class ReadNum
{ 
   public static void main (String[] args) 
   {
       Scanner inFile = null;
       try
       {
           int num1, num2;  // To hold numbers read from the file
           int sum; //To hold sum

           // Create the scanner object for file input.
           inFile = new Scanner(new FileReader("sample.txt"));

           // Read numbers from the file.
           num1 = inFile.nextInt();
           num2 = inFile.nextInt();

           // Calculate total.
           sum = num1 + num2;

           // Print total.
           System.out.println("sum " + sum);
       } 
       catch (FileNotFoundException ex)
       {
           System.out.println("Error "+ ex);
       }
       catch (InputMismatchException ex)
       {
           System.out.println("Error "+ ex);
       }
       catch (Exception ex)
       {
           System.out.println("Error "+ ex);
       }
       finally
       {
           // Close the file.
           if(inFile != null)
                inFile.close();
       }
   }
}
\$\endgroup\$

2 Answers 2

10
\$\begingroup\$

Your code is interesting, in the sense that it appears to have been pulled from about 4 different text books all related to Java about 4 versions ago.... actually, make it Java 1.3.

It is consistent code, but everything is just.... old.

In some sense of order, the following strike me most:

  1. multicatch
  2. try with resources
  3. don't catch Exception
  4. don't just print the exception's toString, print the full stack.
  5. Brace on same line
  6. don't *-import.
  7. don't pre-declare variables... declare at use-time.
  8. redundant comments

On the other hand, your variable names are great, and the basic concept is sound.

Here's my version of your code:

import java.io.FileReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class ReadNum {
    public static void main(String[] args) {
        try (Scanner inFile = new Scanner(new FileReader("sample.txt"))) {

            int num1 = inFile.nextInt();
            int num2 = inFile.nextInt();

            int sum = num1 + num2;

            System.out.println("sum " + sum);
        } catch (IOException | InputMismatchException ex) {
            ex.printStackTrace();
        }
    }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I had the comment one. When I used to have to submit code I would put a paragraph explaining how the sparsity of comments was not me forgetting to comment. I'd love to be able to convey "I don't need to write 'class for reading numbers' above the line 'public class ReadNum' to know what ReadNum does" \$\endgroup\$
    – Alec Teal
    Commented May 10, 2015 at 15:59
2
\$\begingroup\$

Note that you actually do not handle the exceptions. It's not your fault, as there's not enough context for really handling them. Is printing the stacktrace to the error output appropriate? In this case it may be the right thing, but usually it's not. Surprisingly, doing nothing is mostly best - note that the java.io classes also throw without any "handling".

So I'd simplify rolfl's code to

public static void main(String[] args) throws IOException, InputMismatchException {
    try (Scanner inFile = new Scanner(new FileReader("sample.txt"))) {

        int num1 = inFile.nextInt();
        int num2 = inFile.nextInt();

        int sum = num1 + num2;

        System.out.println("sum " + sum);
    }
}

When an exception gets thrown, the stacktrace gets printed anyway (in my solution the exact behavior is OS dependent, but this may be an advantage).

There's one more difference: Not catching means that the program returns a non-zero status (on systems supporting it, i.e., at least UNIX and Windows), which clearly indicates a problem.

\$\endgroup\$
2
  • \$\begingroup\$ I wanted to comment on rolfl's answer, but since you're doing some simplification too, you can also consider: System.out.println("sum " + (inFile.nextInt() + inFile.nextInt())); \$\endgroup\$
    – h.j.k.
    Commented May 11, 2015 at 0:59
  • 1
    \$\begingroup\$ @h.j.k. Sure, this works in Java, where you can depend on the side effect order. It actually works in any language due to + being commutative. So I'd go for it. \$\endgroup\$
    – maaartinus
    Commented May 11, 2015 at 1:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.