Handling exceptions with FileInputStream Could you please tear my code apart? It's an exercise from CodeGym. Recently I changed a few things within my coding practices, namely:


Not writing all my solutions on main. Instead, trying to create methods to make the code more organised. 
Instantiating the class on main to call the methods.
Using try with resources
Pay close attention to indentation


I have on specific question. What types of comments would you write on that code, if any. 

Thanks!

/* 
ABCs
The first parameter of the main method is a file name.
Count the letters of the English alphabet in the file.
Display the number of letters.
Close the streams.


Requirements:
1. You don't need to read anything from the console.
2. Create a stream to read from the file passed as the first argument of the main method.
3. You need to count the letters of the English alphabet in the file and display the number.
4. You must count both uppercase and lowercase letters.
5. The stream used to read the file must be closed.

*/

import java.io.FileInputStream;
import java.io.IOException;

public class Solution {
    private void countLetters (String args) {
        char[] array = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
                'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

        int count = 0;
        try (FileInputStream in = new FileInputStream(String.valueOf(args))) {
            int ch;
            while ((ch = in.read()) != -1) {
                for (int i = 0; i &lt; array.length; i++) {
                    if (ch == array[i]) {
                        count++;
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("General I/O exception: " + e.getMessage());
        }

        printCount(count);
    }

    private void printCount (int count) {
        System.out.println(count);
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        solution.countLetters(args[0]);
    }
}
Naming

Class name Solution does not describe the purpose of the class beyond it being a solution to some random assignment. For the sole purpose of archiving exercises I would name the package with the identifier of the assignment and use a more descriptive class name: your.domain.codegym.exercise42.LetterCounter and put the URL to the assignment in the JavaDoc (maybe package.html). BTW: If you haven't done already, I recommend setting up a GitLab repo for your exercises. One of my regrets is that I've lost so much code I wrote when I was young because broken hard disks and obsoleted hardware. We didn't have on-line repos then...

The parameter name args in the countLetters method does not tell what it is supposed to contain and it is misleading as the plural suffix 's' implies that the parameter would contain multiple values. The parameter should be named as fileName.

Unnecessary object initialization

The method countLetters does not rely on any member variable from the Solution class and the counter does not hold any state between invocations to countLetters. There is no need for the method to require a the Solution class to be instantiated. It could very well be a public static void countLetters(...). If the assignment required that an object is to be initialized, then the requirement is a bit artificial.

Inefficient algorithm

The array that contains the english alphabet letters never changes. It should be a static field in the Solution class. As it is now, your code allocates a new array for the alphabet every time your method is called. But an array like this is also a very inefficient way to look for a letter. As the US-ASCII charset fits in 7 bits and the upper and lower case letters form two consecutive blocks in the character table. You can simply compare the character to first and last letter:

if ((ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') || (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z')) {
    count++;
}


Note that this approach does not work if the text in the file is in a character set that does not inherit US-ASCII. That would be very very rare these days.

Multiple responsibilities

The countLetters method is a utility method. It should have exactly one purpose so that it does not unnecessarily limit it's usability (also maintaining the single responsibility principle helps in maintainability and testability). You should not implement exception handling beyond closing the resources you have acquired in the method. So instead of printing out the error message, you should just let the exception escape and let caller decide how to handle the error.

So the countLetters has three responsibilities: it counts the letters in a file, handles error logging and also implements output handling. Instead of printing the letter count the method should just return the number of letters and let the caller handle the output. Use long instead int. Files can be large.

private long countLetters (String args) throws IOException {
    ...
    return count;
}


Error handling

For future reference, it is almost never correct to write errors to System.out. The correct stream for errors is System.err. And logging n exception simply with the exeption message causes trouble when you're trying to debug problems, because all the important information in the exception is in the stack trace. If you have to log an exception to the console, simply write ex.printStackTrace();. In the real world you would use a loging framework but still you would log the full stack trace, never just the message.

Add a check to see if the args array in the main method contains exactly one element. If you do not provide parameters to your program now you get an ArrayIndexOutOfBoundsExceltion.

Monolithic code

You've tried to not implement all your logic in the main method, but the attempt falls a bit short because the methods in the Solution class are all private. The only way to access the counter is is still via the main method only. Instead of implementing the main method to the Solution-class you should have two classes: one that implements the letter counting and one that has the main method, which invokes the letter counter class. I.e. separate the letter counting responsibility from the command line processing responsibility. This again follows the single responsiblity principle: the Solution-class is only responsible for counting. All other responsibilities are put into separate modules.