Good day,
Why in video lessons one human was not using try-catch, and, if i not be using try-catch i have an error IOException on createnewFile(), FileWriter etc.
Maybe this is easy, i from c++, its big question for me.
Thats my code:
PS. Sorry for "best english"
public static void main(String[] args) {
System.out.println("Hello World");
File file1 = new File("temp.txt");
if(!file1.exists()) {
System.out.println("Creating file...");
try
{
file1.createNewFile();
}
catch (IOException e)
{
e.printStackTrace();
}
}
try
{
FileWriter fw = new FileWriter(file1);
BufferedWriter out = new BufferedWriter(fw);
out.write("aString");
out.flush();
out.close();
FileReader fr = new FileReader(file1);
BufferedReader in = new BufferedReader(fr);
while(in.ready()) {
System.out.println(in.readLine());
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
We use try- catch block to maintain the flow of execution of code.
If exception occurs it goes to catch block and e.printStackTrace it gives us the information why exception occurs and we can handle it here with our logic.
if we dont use try-catch the flow of code is stuck where exception occurs.
So thats why we use try-catch block.
Java requires that you handle checked exceptions in your code, either by specifying that your method can throw the exception or by handling it with a try-catch block. If you don't do one of these two at the point where you call a method that may throw a checked exception such as IOException, the compiler is going to produce an error.
You can learn about exceptions in Java here: Lesson: Exceptions (Oracle Java Tutorials).
Specifically: The Catch or Specify Requirement
Related
I am beginner in Java programming. But i have code below
Socket socket = serverSocketObj.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
try {
writer.writeLine();
} catch(IOException e ) {
//write to logger here
} finally {
writer.close(); // this throws IOExceptioin too. What to do with it
// Possible memmory leak?
socket.close();
}
When i try to close writer i should handle another Exception. But i don't know what to do with it. Is this Exception impossible in my case? Can i just ignore it?
If you don't know what to do with them, just catch them and log them.
The simplest way of logging them is e.printStackTrace() This way,
at least you'll always see there's a problem if an exception occurs.
Another approach is to just re-throw the exceptions to upper-level code.
E.g. if your method (in which your sample code is) declares to throw IOException,
then there's nothing you should worry about. Let upper-level code worry about it.
Just check if the writer and socket are not null.
Socket socket = serverSocketObj.accept();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
try {
writer.writeLine();
} catch(IOException e ) {
//write to logger here
} finally {
if(writer != null)
writer.close(); // this throws IOExceptioin too. What to do with it
// Possible memmory leak?
if(socket != null)
socket.close();
}
Unfortunately, to make the compiler happy you must catch the potential IOExceptions from the close statements (assuming you don't add IOException to your method's throws clause). (Thank you Mr Goodenough!)
But there's nothing you can really do to "handle" the exception once you have it, other than to log it.
(I'm thinking that the new "try with resources" structure in Java may handle this all a bit cleaner.)
Hi can we use both try with resources and multi-catch together in Java 7? I tried to use it and it gives compilation error. I may be using it wrongly. Please correct me.
try(GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(f));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip))
{
br.readLine();
}
catch (FileNotFoundException | IOException e) {
e.printStackTrace();
}
Thanks in advance.
Yes! you can.
But, your problem is in FileNotFoundException with IOException. Because FileNotFoundException is subclass of IOException, which is invalid. Use only IOException in catch block. You have also missing the one right parenthesis ) in try statement. Thats why, you got errors.
try(GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(f));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip)))
{
br.readLine();
}
catch (IOException e) {
e.printStackTrace();
}
This is very much possible in Java SE 7. A piece from the official Oracle Documentation :
The new syntax allows you to declare resources that are part of the try block. What this means is that you define the resources ahead of time and the runtime automatically closes those resources (if they are not already closed) after the execution of the try block.
public static void main(String[] args)
{
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
new URL("http://www.yoursimpledate.server/").openStream())))
{
String line = reader.readLine();
SimpleDateFormat format = new SimpleDateFormat("MM/DD/YY");
Date date = format.parse(line);
} catch (ParseException | IOException exception) {
// handle I/O problems.
}
}
#Masud in right in saying the FileNotFoundException is a subclass of IOException, and that they cannot be used like
catch (FileNotFoundException | IOException e) {
e.printStackTrace();
}
But you certainly can do something like this:
try{
//call some methods that throw IOException's
}
catch (FileNotFoundException e){}
catch (IOException e){}
Here's a Java tip that is very useful : When catching exceptions, don't cast your net too wide.
Hope it helps. :)
I am wondering if the below code closes InputStream in finally block correctly
InputStream is = new FileInputStream("test");
try {
for(;;) {
int b = is.read();
...
}
} finally {
try {
is.close();
} catch(IOException e) {
}
}
If an exception happens during is.read() will be it ignored / suppressed if an exception happens during is.close()?
Best way is to use Java 7 and use try with resources, or do same thing manualy and add exception from closing as suppressed exception.
Pre Java 7:
If you are throwing your custom exception, you can add in it supressed exception like it is done in Java 7 (in your exception create fields List suppressed and put there exceptions from close operation and when dealing with your exception, look there too.
If you cannot do that, I don't know anything better than just log it.
examples:
from Java tutorials
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
but better form is:
static String readFirstLineFromFile(String path) throws IOException {
try (FileReader fr = new FileReader(path);
BufferedReader br = new BufferedReader(fr)) {
return br.readLine();
}
}
This way even if creation of FileReader is succesfull but creation of BufferedReader fails (eg not enough memory), FileReader will be closed.
You can close it with IOUtils from https://commons.apache.org/proper/commons-io/
public void readStream(InputStream ins) {
try {
//do some operation with stream
} catch (Exception ex) {
ex.printStackTrace();
} finally {
IOUtils.closeQuietly(ins);
}
}
The Java 6 specs say
If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
So you are right, you will lose the original exception.
The solution probably is to write your finally block so defensively that it is a bigger surprise (worth propagating) if the finally block fails than if an exception comes out of the try catch block.
So, for example, if it is possible that the stream may be null when you try to close it, check it:
InputStream is = new FileInputStream("test");
try {
for(;;) {
int b = is.read();
...
}
} finally {
try {
if( is!=null ) {
is.close();
}
} catch(IOException e) {
}
}
In Java 7, Alpedar's solution is the way to go of course.
The exception from is.close() will be suppressed and the exception from is.read() will be the one that propagates up.
With the code you posted:
If is.close() throws an IOException, it gets discarded and the original exception propagates.
If is.close() throws something else (a RuntimeException or an Error), it propagates and the original exception is discarded.
With Java 7, the correct way to close an InputStream without loosing the original exception is to use a try-with-resources statement:
try (InputStream is = new FileInputStream("test")) {
for(;;) {
int b = is.read();
// ...
}
}
Prior to Java 7, what you do is just fine, except you may want to catch all exceptions instead of just IOExceptions.
Based on your code sample if an exception occurs at the int b = is.read(); point, then the exception will be raised higher up the call chain.
Note though that the finally block will still execute and if the Inputstream invalid another exception will be thrown, but this exception will be "swallowed", which may be acceptable depending on your use case.
Edit:
Based on the title of your question, I would add that what you have is fine in my opinion. You may want to additionally add a catch block to explicitly handle (or perhaps wrap) any exception within the first try block, but it is also acceptable to let any IO exceptions raise up - this really depends on your API. It may or may not be acceptable to let IO exceptions raise up. If it is, then what you have it fine - if it isn't then you may want to handle/wrap the IO exception with something more suitable to your program.
How about the next solution:
InputStream is = new FileInputStream("test");
Exception foundException=null;
try {
for(;;) {
int b = is.read();
...
}
} catch (Exception e){
foundException=e;
}
finally {
if(is!=null)
try {
is.close();
} catch(IOException e) {
}
}
//handle foundException here if needed
If an exception happens during is.read() will be it ignored / suppressed if an exception happens during is.close()?
Yes. You have a catch block for the exception in close() which does not re-throw the exception. Ergo it is not propagated or rethrown.
This is the sample to help to understand your problem,
if you declare the scanner in the try-catch block it will give compiler warning the resource is not closed.
so either make it locally or just in try()
import java.util.InputMismatchException;
import java.util.Scanner;
class ScanInt {
public static void main(String[] args) {
System.out.println("Type an integer in the console: ");
try (Scanner consoleScanner = new Scanner(System.in);) {
System.out.println("You typed the integer value: "
+ consoleScanner.nextInt());
} catch (InputMismatchException | ArrayIndexOutOfBoundsException exception) {
System.out.println("Catch Bowled");
exception.printStackTrace();
}
System.out.println("----------------");
}
}
Which would be considered more proper technique for implementing a try/catch in Java:
A:
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
try {
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (IOException e) {
e.printStackTrace();
}
} catch(FileNotFoundException e) {
e.printStackTrace();
}
or B:
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Also, is it wrong to follow the try/catch block with a long block of code that makes use of the BufferedReader, or is it preferred to include the long block of code inside the try/catch?
For example:
public static void main(String[] args) {
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Long block of code using inFile
inFile.readLine();
inFile.close();
Versus:
public static void main(String[] args) {
Date lastMod = null;
BufferedReader inFile = null;
try {
inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"));
lastMod = new Date(Long.parseLong(inFile.readLine()));
//Long block of code using inFile
inFile.readLine();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
inFile.close();
}
B is much more readable, when there is nothing going on after the internal try block, before the external try block. If you have logic to perform in between, then you must use A
In the second example the second version using finally is critical to ensure that close will be called no matter what (even if the function returns first) The first version without finally is actually wrong, since you may use up all the file handles and be unable to open more files.
As an additional note, you may need to check for null when calling close. And if you are using java 7, it's even better to use "try with resources".
For the first question: the solution A add unnecessary complexity. Use B or, if you are using Java 7, try-with-resources:
Date lastMod = null;
try (BufferedReader inFile = new BufferedReader(new FileReader("C:\\Java\\settings.ini"))){
lastMod = new Date(Long.parseLong(inFile.readLine()));
} catch (FileNotFoundException | IOException e) {
e.printStackTrace();
}
For the second question: in the first version, what if the BufferedReader creation throws an exception? You would use brafter which is null and would throw a NullPointerException. Also if something else happen, you will not have called inFile.close(), so you really need a finally. For all these reasons, again, the second solution is better.
If you are using try-with-resouces (Java 7), of course, you don't need a finally block to release your BufferedReader.
Proper technique might also include not catching your exceptions, but allowing them to bubble up to a caller instead. Do always use a finally block to clean up any state that might otherwise use up resources, but you'll often be better off catching the exception in the parent routine rather than the child routine in which the exception was thrown.
In general, if it would be helpful to know in the calling routine whether the sub-routine succeeded or not, then that sub-routine should not catch its exceptions, but should allow them to bubble up to their caller.
I'm learning java and one thing I've found that I don't like, is generally when I have code like this:
import java.util.*;
import java.io.*;
public class GraphProblem
{
public static void main(String[] args)
{
if (args.length < 2)
{
System.out.println("Error: Please specify a graph file!");
return;
}
FileReader in = new FileReader(args[1]);
Scanner input = new Scanner(in);
int size = input.nextInt();
WeightedGraph graph = new WeightedGraph(size);
for(int i = 0; i < size; i++)
{
graph.setLabel(i,Character.toString((char)('A' + i)));
}
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
graph.addEdge(i, j, input.nextInt());
}
}
// .. lots more code
}
}
I have an uncaught exception around my FileReader.
So, I have to wrap it in a try-catch to catch that specific exception. My question is does that try { } have to encompass everything after that in my method that wants to use either my FileReader (in) or my Scanner (input)?
If I don't wrap the whole remainder of the program in that try statement, then anything outside of it can't access the in/input because it may of not been initialized or has been initialized outside of its scope. So I can't isolate the try-catch to just say the portion that intializes the FileReader and close the try statement immediately after that.
So, is it the "best practice" to have the try statement wrapping all portions of the code that are going to access variables initialized in it?
Thanks!
If you are comfortable with not wrapping the code after the FileReader constructor, you can declare the FileReader outside of the try/catch block, like this:
FileReader fr = null;
try
{
fr = new FileReader(args[1]);
}
catch (IOException e)
{
// handle
}
// code that uses fr
This is a reasonable design, and I use it often. Make sure you properly handle, in the following code, the possibility that fr is null (i.e. the constructor threw an exception).
This is not an issue with try/catch blocks as such. The issue is variable scoping and that you must have a try/catch block because of the checked exception and thus establish a new scope.
You also have another option - declare the checked exception(s) as throws from your method.
public static void main(String[] args) throws IOException {
// ...code here...
}
This is perfectly legal for a main method.
If you do want to handle the exception, as you ought to in a larger program. You can define a specific try/catch around the problem block of code and use the variable outside of the scope by declare the variable outside of that scope as many have answered:
FileReader fr = null; // must be initialized here if the exception handling code
// does not exit the method
try {
fr = new FileReader(fileName);
} catch (IOException ex) {
// log, print, and/or return
// if you return or exit here then subsequent code can assume that fr is valid
}
You can also put the move the code to another method that deals with the exception:
private static FileReader openReader(String fileName) {
try {
return new FileReader(fileName);
} catch (IOException ex) {
// log/print exception
return null; // caller must then expect a null
// or
throw new RuntimeException(...); // throw a RuntimeException of some kind (may not be good practice either)
}
}
You could also move the file processing code to another method. This may be better and allow you to more correctly follow the open/close in finally idiom:
FileReader fr = null;
try {
fr = new FileReader(fileName);
Scanner input = new Scanner(fr);
processInput(input);
} catch (IOException ex) {
// log/print exception
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException ex) {
// empty
}
}
}
private static void processInput(Scanner in) throws IOException {
// ...processing here
}
For the close part, you could use a third party library (Apache File Utils) or write a simple method to provide a static safe close method that doesn't throw exceptions.
You really should look at breaking up large methods into smaller units and this will often provide you with a much clearer way of handling the exceptions as well.
No. You can declare it like this:
FileReader in = null;
Scanner input = null;
try {
in = new FileReader(args[1]);
input = new Scanner(in);
} catch(IOException ioe) {
//
}
Yes and no. The Try initiates it's own local scope so when you do this:
try
{
FileReader reader = new FileReader(args[1]);
// Stuff
}
catch(Exception e) { }
The reader variable is only visible within the constraints of the try {} block. This is preferred behaviour. If you want to use it outside (in the case of file i/o it's not reccomended) you need to declare it outside of the try/catch. A proper example would be a flag:
boolean isValidFile = false;
try
{
FileReader reader = new FileReader(args[1]);
// Do Stuff
isValidFile = true;
}
catch(Exception e)
{
// Handle Errors
}
System.out.print("Valid File: ");
System.out.println(isValidFile);
If you are just learning, you can have your method throw Exception. It isn't a great way to handle exceptions however, if you are just learning, you probably want to focus more on the logic of what your code is doing. Once you are comfortable with that, then you can look into handling exceptions properly.
So your code should look like the following and you won't have to worry about try/catch statements:
public class GraphProblem {
public static void main(String[] args) throws Exception {
//your code
}
}
Again, this is not a best practice but it allows you to focus on your business logic rather than error handling. Once you get comfortable with the business logic, then you can dig into exception handling which is a topic onto itself.
Local variables declared within a block are scoped to that block.
So, is it the "best practice" to have the try statement wrapping all portions of the code that are going to access variables initialized in it?
In general, you should try to minimize the scope of your variables to make them as narrow as possible. This is covered in Effective Java and Code Complete, among others.
This sort of code is a recipe for NullPointerExceptions:
FileReader in = null;
try {
in = new FileReader(filename);
} catch(IOException e) {
//handle error, but now what?
}
// Code that needs "in", but what if it is null
// because of a FileNotFoundException?
// This code is junk.
Virtually all local variable declarations should include an assignment.
FileReader in = new FileReader(filename);
If you follow this rule of thumb, you'll end up with better code.
// .. lots more code
If you have giant try/catch statements, it sounds like your methods are too big. This is a code organization issue rather than something to do with try/catch specifically.
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("Error: Please specify a graph file!");
return;
}
try {
processGraphFile(args[0]);
} catch (IOException e) {
// Deal with error
}
}
private static void processGraphFile(String filename) throws IOException {
FileReader in = new FileReader(filename);
try {
Scanner scanner = new Scanner(in);
processGraph(scanner);
if (scanner.ioException() != null) {
throw scanner.ioException();
}
} finally {
in.close();
}
}
//other methods
As an aside:
Note that Java arrays start at index 0, not 1
The FileReader is convenient while learning, but should generally be avoided due to encoding issues; this is unlikely to be a problem until the code leaves your machine
You should definitely follow the pattern above. If I remember right from my SCJP studying, the compiler doesn't try to optimize anything that is in a try block, so you should try-catch at the lowest level possible.