Try-Catch-Finally - Final Block not recognising variable - java

firstly I know I should be using a try-catch with resources, however I don't currently have the most up to date JDK on my system.
I have the following code below, and am trying to ensure the resource reader is closed using the finally block, however the code below doesn't compile for two reasons. Firstly is that reader may have not been initialized and secondly that close() should be caught within its own try-catch. Dont both of these reasons defeat the object of the initial try-catch block?
I can solve the issue with the finally block close() statement by putting it in its own try-catch. However this still leaves the compile error about reader not being initialized?
I'm presuming I have gone wrong somewhere? Help appreciated!
Cheers,
public Path [] getPaths()
{
// Create and initialise ArrayList for paths to be stored in when read
// from file.
ArrayList<Path> pathList = new ArrayList();
BufferedReader reader;
try
{
// Create new buffered read to read lines from file
reader = Files.newBufferedReader(importPathFile);
String line = null;
int i = 0;
// for each line from the file, add to the array list
while((line = reader.readLine()) != null)
{
pathList.add(0, Paths.get(line));
i++;
}
}
catch(IOException e)
{
System.out.println("exception: " + e.getMessage());
}
finally
{
reader.close();
}
// Move contents from ArrayList into Path [] and return function.
Path pathArray [] = new Path[(pathList.size())];
for(int i = 0; i < pathList.size(); i++)
{
pathArray[i] = Paths.get(pathList.get(i).toString());
}
return pathArray;
}

There is no other way then initialize your buffer and catch the exception. The compiler is always right.
BufferedReader reader = null;
try {
// do stuff
} catch(IOException e) {
// handle
} finally {
if(reader != null) {
try {
reader.close();
} catch(IOException e1) {
// handle or forget about it
}
}
}
The method close will always need a try-catch-block since it declares that it could throw an IOException. It doesn't matter if the call is in a finally block or somewhere else. It just needs to be handled. It is a checked exception.
Read must also be initialized just by null. IMHO this is super useless, but that's Java. That is how it works.

Instead check if reader is null or not and then close it accordingly like below (you should call close() on reader only if it's not null or if it's been already instantiated else you will end up getting null reference exception).
finally
{
if(reader != null)
{
reader.close();
}
}

Related

Return in Catch Statement

At the following program, in case I remove the return statement from:
catch(FileNotFoundException e) {
System.out.println("File Not Found");
return;
It shows me an error inside the do while loop, that the local variable fin might not have been initialized. Can someone explain me why is this happening?
import java.io.*;
class Stock {
public static void main(String args[])
throws IOException {
int i;
FileInputStream fin;
try {
fin = new FileInputStream(args[0]);
} catch(FileNotFoundException e) {
System.out.println("File Not Found");
return;
}
// read characters until EOF is encountered
do {
i = fin.read();
if(i != -1) System.out.print((char) i);
} while(i != -1);
fin.close();
}
}
If you remove the return statement, you get:
public static void main(String args[])
throws IOException {
int i;
FileInputStream fin;
try {
fin = new FileInputStream(args[0]);
} catch(FileNotFoundException e) {
System.out.println("File Not Found");
}
// read characters until EOF is encountered
do {
i = fin.read();
if(i != -1) System.out.print((char) i);
} while(i != -1);
fin.close();
}
Now if FileInputStream throws an exception, it doesn't return a result, and fin doesn't get initialized. The catch block handles the exception and prints a message, but then the code continues, and the next thing it tries to execute is i = fin.read(). Since the compiler figures out that there's a possible way to get to this statement without initializing fin or assigning anything to it, it won't compile the program.
If you put the return back in, this can't happen, because the catch block will cause main to return, and you can't get to fin.read().
The exception could have been thrown in the call in the try block, so no value will have been assigned to the variable fin. Without the return statement, the subsequent use of the uninitialized fin variable causes the compiler to complain.
With the return statement, if the fin variable is never initialized, it is never used, either, so the compiler is okay with that.
Why compiler complain
- if your main() encounter the exceptions it will pass try catch block and never get the
chance to initialize fin variable
- Compiler knows that program may end up with throwing an exception which has high chance
in order to avoid any fruther issue it will not complie
I advise you to do this
- use try catch block with resources since Java 7 since Class `FileInputStream` is `closable`
- put everything in a good order
code:
try(FileInputStream fin =new FileInputStream(args[0]) ) {
while ((content = fin.read()) != -1) {
// convert to char and display it
System.out.print((char) content);
}
} catch(FileNotFoundException e) {
System.out.println("File Not Found");
return;
} ...
....
..
Source:
http://docs.oracle.com/javase/7/docs/api/java/io/FileInputStream.html
http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html
An exception could occur in new FileInputStream(args[0]);, which would cause fin to not have been initialized.
Try using a default value for fin:
fin = null;
Then later, check to make sure it is not null:
if (fin != null)
{
do {
i = fin.read();
if(i != -1) System.out.print((char) i);
} while(i != -1);
fin.close();
}
If an exception is encountered while instantiating the FileInputStream, then control moves to the catch block before a value is stored in the variable fin. Without the return statement in place the program would continue execution into the do/while loop, where a method (read) would be called on the uninitialized variable, resulting in an error.

java lazy code after return using try - finally

I have discovered possibility of having code "after return" using finally, here is some example:
int foo() {
BufferedReader br = ...;
try {
// cca 20 lines with 4 returns in different if-else clauses etc
//example:
if(something) {
return 0;
} else {
return 1;
}
} finally {
br.close();
}
}
As (in my opinion much more lazy) alternativity to:
int foo() {
BufferedReader br = ...;
int toReturn;
// cca 20 lines with 4 ASSIGMENTS in different if-else clauses etc
//example:
if(something) {
toReturn = 0;
} else {
toReturn = 1;
}
br.close();
return toReturn;
}
So, the question is, which is faster, more readable, and yes, in this case, i am really closing a BufferedReader, so is try-finnaly for this or am i using it wrong way?
Without using the try/catch/finally, if an exception is thrown, your BufferedReader won't be closed properly, causing a memory leak, potential unwanted file locking...
Using finally, your BufferedReader will be closed, even if an exception is thrown while processing the try block.
But as your BufferedReader instantiation can also throw an exception, you should include it in your try block:
BufferedReader br = null;
try {
br = ...;
// do your stuff
}
catch (Exception e) {
// handle exception
}
finally {
if(br != null)
br.close();
}
If you're using Java 7 or newer, go with the elegant Try-with-resources, as stated by Arnaud.
If there is an exception throws, both your code fail since first case you are not catching exception and second case there are no evidence of handling exception.
finally will execute any way here.
If your BufferedReader get input by file read, in a case which file not found both ways are not useful.
The second one is actually unacceptable. You will not close the buffer in case of exception.
I advise you to use the try-with-resources statement (intended for that purpose):
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
//do what you want with the buffer. It will automatically be closed.
return;
}
See The try-with-resources Statement
am i using it wrong way?
yes you are. What if say something is a method call and it throws exception, then your br is never closed. While finally makes sure that in any case it will get execute*
`* - there are some conditions where you can avoid finally clause execution

Trying to output a string variable to a .txt file within an IF statement. - Java

I'm pretty new to java and i still have alot to learn. I'm trying to output the data within a variable to a text file, and I'm not sure why this will not work. Could anyone help me out?
if ("Y".equals(output_to_file)) {
System.out.print("You selected Yes");
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream("filename.txt"));
out.print(first_input);
}
finally {
if (out != null) out.close();
}
}
else System.out.print("You selected No");
"(new FileOutputStream("filename.txt"))" is underlined red, and it says: Unhandled exception: java.io.FileNotFoundException
Thanks for your help!
Anytime you're doing file operations, there is the possiblity that a FileNotFoundException will be thrown. Therefore, Java wants you to tell it what to do in the event that one is thrown. Thus, you need to add a catch clause for the possible FileNotFoundException. You already have a try block, so you simply need to add a catch clause before your finally clause:
try {
out = new PrintStream(new FileOutputStream("filename.txt"));
out.print(first_input);
}
catch(FileNotFoundException e) {
//do something in the event that a FNFE is thrown
}
finally {
if (out != null) out.close();
}
}

How do I return a String in a try/catch statment?

I am trying to return a String from the following method.
public String openCon() {
try {
Scanner scan = new Scanner(System.in);
URL sitex = new URL("http://" + scan.nextLine());
URLConnection connection = sitex.openConnection();
Object content = sitex.getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(sitex.openStream()));
String str;
String x = "1";
while ((str = in.readLine()) != null) {
x += str;
}
in.close();
return x;
}
catch(Exception e) {
System.out.println(e);
}
}
The problem isn't returning from the try block - the problem is that you aren't returning anything if an exception is thrown. You're catching the exception... but then reaching the end of the method without returning anything. (To put it in more technical terminology: the end of a non-void method should not be reachable.)
Personally, I would just remove the catch block entirely, and add throws declarations for any exceptions which are thrown within the body. You're not really handling the exceptions - you're just printing them out and ignoring them, which is very rarely a good idea. Catching Exception is usually a pretty bad idea to start with.
As an aside, you should also close your BufferedReader and URLConnection values in a finally block so they're closed even in the case of an exception. I'd also suggest either passing a fixed encoding name to InputStreamReader, or using a higher-level HTTP client API which will use the content-type header from the response. Oh, and use StringBuilder instead of string concatenation in a loop.
Why not initialise the variable before the try statement, and place the return statement after it?
If there's an exception before the return statement, the method won't return anything. Since you're not really handling the exception, I recommend you just let it bubble up and handle it at a higher level. This may be the main method if there's no better place. You will need to declare the method as throws IOException and possibly add other exception classes.
Also, use try-with-resources to ensure your instances (BufferedReader and InputStreamReader) are closed properly.
You should return something in the catch block, for example:
catch(Exception e) {
System.out.println(e);
return "";
}
Use:
String result = ""
try{
result = "OK";
}catch (Exception e){
result = e.toString();
}finally{
return result;
}

Java File Handling, what did I do wrong?

Wrote up a basic file handler for a Java Homework assignment, and when I got the assignment back I had some notes about failing to catch a few instances:
Buffer from file could have been null.
File was not found
File stream wasn't closed
Here is the block of code that is used for opening a file:
/**
* Create a Filestream, Buffer, and a String to store the Buffer.
*/
FileInputStream fin = null;
BufferedReader buffRead = null;
String loadedString = null;
/** Try to open the file from user input */
try
{
fin = new FileInputStream(programPath + fileToParse);
buffRead = new BufferedReader(new InputStreamReader(fin));
loadedString = buffRead.readLine();
fin.close();
}
/** Catch the error if we can't open the file */
catch(IOException e)
{
System.err.println("CRITICAL: Unable to open text file!");
System.err.println("Exiting!");
System.exit(-1);
}
The one comment I had from him was that fin.close(); needed to be in a finally block, which I did not have at all. But I thought that the way I have created the try/catch it would have prevented an issue with the file not opening.
Let me be clear on a few things: This is not for a current assignment (not trying to get someone to do my own work), I have already created my project and have been graded on it. I did not fully understand my Professor's reasoning myself. Finally, I do not have a lot of Java experience, so I was a little confused why my catch wasn't good enough.
Buffer from file could have been null.
The file may be empty. That is, end-of-file is reach upon opening the file. loadedString = buffRead.readLine() would then have returned null.
Perhaps you should have fixed this by adding something like if (loadedString == null) loadedString = "";
File was not found
As explained in the documentation of the constructor of FileInputStream(String) it may throw a FileNotFoundException. You do catch this in your IOException clause (since FileNotFoundException is an IOException), so it's fine, but you could perhaps have done:
} catch (FileNotFoundException fnfe) {
System.err.println("File not fonud!");
} catch (IOException ioex {
System.err.println("Some other error");
}
File stream wasn't closed
You do call fin.close() which in normal circumstances closes the file stream. Perhaps he means that it's not always closed. The readLine could potentially throw an IOException in which case the close() is skipped. That's the reason for having it in a finally clause (which makes sure it gets called no matter what happens in the try-block. (*)
(*) As #mmyers correctly points out, putting the close() in a finally block will actually not be sufficient since you call System.exit(-1) in the catch-block. If that really is the desired behavior, you could set an error flag in the catch-clause, and exit after the finally-clause if this flag is set.
But what if your program threw an exception on the second or third line of your try block?
buffRead = new BufferedReader(new InputStreamReader(fin));
loadedString = buffRead.readLine();
By this point, a filehandle has been opened and assigned to fin. You could trap the exception but the filehandle would remain open.
You'll want to move the fin.close() statement to a finally block:
} finally {
try {
if (fin != null) {
fin.close();
}
} catch (IOException e2) {
}
}
Say buffRead.readLine() throws an exception, will your FileInputStream ever be closed, or will that line be skipped? The purpose of a finally block is that even in exceptional circumastances, the code in the finally block will execute.
There are a lot of other errors which may happen other than opening the file.
In the end you may end up with a fin which is defined or not which you have to protect against null pointer errors, and do not forget that closing the file can throw a new exception.
My advice is to capture this in a separate routine and let the IOExceptions fly out of it :
something like
private String readFile() throws IOException {
String s;
try {
fin = new FileInputStream(programPath + fileToParse);
buffRead = new BufferedReader(new InputStreamReader(fin));
s = buffRead.readLine();
fin.close();
} finally {
if (fin != null {
fin.close()
}
}
return s
}
and then where you need it :
try {
loadedString = readFile();
} catch (IOException e) {
// handle issue gracefully
}

Categories