poetzmij
poetzmij

Reputation: 7

Why must I create inputStream and outputStream with type FileReader/Writer when im creating the objects themselves?

Ok this is the code and my question is why do i have to put FileReader inputstream = null; and the same with FileWriter. Why can't I simply create the objects later in the try block? Am I missing something... I probably am.

public static void main(String[] args) throws IOException{
    // TODO Auto-generated method stub
        FileReader inputStream = null;
        FileWriter outputStream = null;
        try {
            inputStream = new FileReader("In.txt");
            outputStream = new FileWriter("Out.txt");
            int c;
            while ((c = inputStream.read()) != -1){
                outputStream.write(c);

            }
        }
                finally {
                    if (inputStream != null){
                        inputStream.close();
                    }
                    if (outputStream != null){
                        outputStream.close();

                }
        }

Upvotes: 0

Views: 1271

Answers (4)

Joop Eggen
Joop Eggen

Reputation: 109593

I often use the following

FileReader in = new FileReader("In.txt");
try {
    // do reading
} finally {
    in.close();
}

This means the enclosing method throws an IOException (i.e. FileNotFoundException). This fits with Java 7 too:

try (FileReader in = new FileReader("In.txt"); FileWriter ...) {
    // do reading
}

Upvotes: 0

Stephen C
Stephen C

Reputation: 719309

It is all about the definite assignment rules. Java will only allow you to use a local variable if it can be guaranteed that the variable has been initialized.

Consider this simplified version of your code:

    FileReader inputStream;  // not initialized here ...
    try {
        inputStream = new FileReader("In.txt");
        // do stuff
    } finally {
        if (inputStream != null) {
            inputStream.close();
        }
    }

No suppose that the FileReader constructor doesn't find the In.txt file, and throws a FileNotFoundException. The constructor terminates "abnormally" and no value gets assigned to inputStream. Then we arrive at the finally block, where we try to test that inputStream is not null. But at that point, inputStream is still uninitialized, and Java won't allow us to take the value of an uninitialized local variable and you get a compilation error.

The seemingly useless assignment of null to inputStream solves the problem by ensuring that the variable has always been initialized when we get to the finally block.


The Java Language Specification devotes a whole chapter to specifying the definite assignment rules; i.e. the rules that the compiler uses to decide if a variable has been initialized at any given point. These rules are rather conservative, and in some cases the compiler will say something is not definitely assigned when a big-brained human can deduce that it is. You just have to live with that, and occasionally add an unnecessary initialization or a return statement that can't ever be executed.

Upvotes: 0

Tassos Bassoukos
Tassos Bassoukos

Reputation: 16152

Because with FileReader inputstream = null you do not create an object, just a reference named inputStream to one. Which one? None, the reference is initialized with null. Later on you may or may not create an object (but what happens if new FileReader(...) throws an exception?); the checks in the finally block need to work on initialized variables.

Upvotes: 0

Bozho
Bozho

Reputation: 597274

Because you won't be able to refer to them in the finally block, and so you won't be able to close them.

Btw, if they are reader and writer, you'd better name the variables that way, rather than xStream.

I/O handling has always been tedious, that's why Java 7 introduced "try with resource"

Upvotes: 2

Related Questions