Reputation: 7
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
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
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
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
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