I initially started programming in college and learnt vb.net. Now I have decided to make the move to Java and have some queries. In vb, the try catch statement is laid out as follows
try
Catch ex as exception
finally
End catch
but from the java website (https://docs.oracle.com/javase/tutorial/essential/exceptions/putItTogether.html)
i found that in java you use two catches like so:
try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}
i was hoping someone could explain why you need two catches in java and what do the respective catches do/catch.
Thanks.
In Java, you can use multiple catch blocks.
It doesn't necessarily means you have to.
It depends on the code your have in the try block, and how many checked Exceptions it may potentially throw (or even unchecked Exceptions if you really want to catch that, typically you don't and you don't have to).
One bad practice is to use a single handler for general Exception (or worse, Throwable, which would also catch RuntimeExceptions and Errors):
try {
// stuff that throws multiple exceptions
}
// bad
catch (Exception e) {
// TODO
}
The good practice is to catch all potentially thrown checked Exceptions.
If some of them are related in terms of inheritance, always catch the child classes first (i.e. the more specific Exceptions), lest your code won't compile:
try {
// stuff that throws FileNotFoundException AND IOException
}
// good: FileNotFoundException is a child class of IOException - both checked
catch (FileNotFoundException fnfe) {
// TODO
}
catch (IOException ioe) {
// TODO
}
Also take a look at Java 7's multi-catch blocks, where unrelated Exceptions can be caught all at once with a | separator between each Exception type:
try (optionally with resources) {
// stuff that throws FileNotFoundException and MyOwnCheckedException
}
// below exceptions are unrelated
catch (FileNotFoundException | MyOwnCheckedException e) {
// TODO
}
Note
In this example you linked to, the first code snippet below Putting it all together may arguably be considered as sub-optimal: it does catch the potentially thrown Exceptions, but one of them is an IndexOutOfBoundsException, which is a RuntimeException (unchecked) and should not be handled in theory.
Instead, the SIZE variable (or likely constant) should be replaced by a reference to the size of the List being iterated, i.e. list.size(), in order to prevent IndexOutOfBoundsException from being thrown.
I guess in this case it's just to provide an example though.
The code that is on the page that is in link i have modified it with single exception. Problem here is that in this case you will not able to know that exception is where whether due to
IndexOutOfBoundsException or IOException
just you know that a exception occurs
import java.io.*;
import java.util.List;
import java.util.ArrayList;
public class ListOfNumbers {
public static void main(String... s) {
ListOfNumbers lon = new ListOfNumbers();
lon.writeList();
}
private List<Integer> list;
private static final int SIZE = 10;
public ListOfNumbers() {
list = new ArrayList<Integer>(SIZE);
for (int i = 0; i < SIZE; i++) {
list.add(new Integer(i));
}
}
public void writeList() {
PrintWriter out = null;
try {
System.out.println("Entering" + " try statement");
out = new PrintWriter(new FileWriter("e://OutFile.txt"));
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i));
}
} catch (Exception e) {
System.err.println("Caught Exception: " + e.getMessage());
} finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
}
}
}
}
Let us understand the concept it is better to know why the code fails due to which particular type of exception whether
IndexOutOfBoundsException or IOException
Now The Code with handling of different Exception
import java.io.*;
import java.util.List;
import java.util.ArrayList;
public class ListOfNumbers {
public static void main(String... s) {
ListOfNumbers lon = new ListOfNumbers();
lon.writeList();
}
private List<Integer> list;
private static final int SIZE = 10;
public ListOfNumbers() {
list = new ArrayList<Integer>(SIZE);
for (int i = 0; i < SIZE; i++) {
list.add(new Integer(i));
}
}
public void writeList() {
PrintWriter out = null;
try {
System.out.println("Entering" + " try statement");
out = new PrintWriter(new FileWriter("e://OutFile.txt"));
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i));
}
} catch (IndexOutOfBoundsException e) {
System.err.println("Caught IndexOutOfBoundsException: " +
e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
}
}
}
}
Here we could come to know that whether it fails due to creation of file at location
e://OutFile.txt
drive Not on my system
error printed as
Caught Exception: e:\OutFile.txt (The system cannot find the path
specified) Entering try statement PrintWriter not open
Next Case
Now when i comment the line
list.add(new Integer(i));
import java.io.*;
import java.util.List;
import java.util.ArrayList;
public class ListOfNumbers {
public static void main(String... s) {
ListOfNumbers lon = new ListOfNumbers();
lon.writeList();
}
private List<Integer> list;
private static final int SIZE = 10;
public ListOfNumbers() {
list = new ArrayList<Integer>(SIZE);
for (int i = 0; i < SIZE; i++) {
// list.add(new Integer(i));
}
}
public void writeList() {
PrintWriter out = null;
try {
System.out.println("Entering" + " try statement");
out = new PrintWriter(new FileWriter("OutFile.txt"));
for (int i = 0; i < SIZE; i++) {
out.println("Value at: " + i + " = " + list.get(i));
}
} catch (IndexOutOfBoundsException e) {
System.err.println("Caught IndexOutOfBoundsException: " +
e.getMessage());
} catch (IOException e) {
System.err.println("Caught IOException: " + e.getMessage());
} finally {
if (out != null) {
System.out.println("Closing PrintWriter");
out.close();
} else {
System.out.println("PrintWriter not open");
}
}
}
}
then it clearly says that it fails for index out of bound exception
Entering try statement Caught IndexOutOfBoundsException: Index: 0,
Size: 0 Closing PrintWriter
So for the purpose of debugging the application properly and efficiently it is good.
I have created condition for the other type of exception
NoClassDefFoundError
java.lang.NoClassDefFoundError: ListOfNumbers
Caused by: java.lang.ClassNotFoundException: stackprac.ListOfNumbers
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Exception in thread "main" Process exited with exit code 1.
Related
public class CatchingExceptions {
private int erroneousMethod(int p) {
if (p == 0) {
throw new IllegalArgumentException();
}
int x = 0x01;
return p / (x >> Math.abs(p)); // this line will throw!
}
The task is to implement the following method to catch and print the two exceptions.
public void catchExceptions(int passthrough) {
erroneousMethod(passthrough); // will throw!
try{
????
} catch (IllegalArgumentException e){
System.out.println("???? ");
}
}
Call the method inside the try block:
public void catchExceptions(int passthrough) {
try{
erroneousMethod(passthrough);
} catch (RuntimeException e) { // catches all unchecked exceptions
String message = e.getMessage() == null ? "" : (": " + e.getMessage());
System.out.println(e.getClass().getSimpleName() + ": " + message);
}
}
Consider this question I was asked in an interview
public class Test_finally {
private static int run(int input) {
int result = 0;
try {
result = 3 / input;
} catch (Exception e) {
System.out.println("UnsupportedOperationException");
throw new UnsupportedOperationException("first");
} finally {
System.out.println("finally input=" + input);
if (0 == input) {
System.out.println("ArithmeticException");
throw new ArithmeticException("second");
}
}
System.out.println("end of method");
return result * 2;
}
public static void main(String[] args) {
int output = Test_finally.run(0);
System.out.println(" output=" + output);
}
}
Output of this program throws ArithmeticException not UnsupportedOperationException
Interviewer simply asked how will i let the client know the original exception raised was of type UnsupportedOperationException not ArithmeticException.
I didn't know that
Never return or throw in a finally block. As an interviewer i would expect that answer.
A crappy interviewer looking for a minor technical detail might expect you know Exception.addSuppressed(). You can not actually read the thrown exception in a finally block so you need to store it in the throw block to reuse it.
So something like that:
private static int run(int input) throws Exception {
int result = 0;
Exception thrownException = null;
try {
result = 3 / input;
} catch (Exception e) {
System.out.println("UnsupportedOperationException");
thrownException = new UnsupportedOperationException("first");
throw thrownException;
} finally {
try {
System.out.println("finally input=" + input);
if (0 == input) {
System.out.println("ArithmeticException");
throw new ArithmeticException("second");
}
} catch (Exception e) {
// Depending on what the more important exception is,
// you could also suppress thrownException and always throw e
if (thrownException != null){
thrownException.addSuppressed(e);
} else {
throw e;
}
}
}
System.out.println("end of method");
return result * 2;
}
I'm building a custom exception which basically is thrown if an array doesn't contain 5 strings. This is what I have so far. The only exception that really matters is the custom one as I just have to show that that exception is thrown if the array doesn't contain the 5 strings after the input file was split. Any help would be appreciated. Thanks!
package exceptions;
import java.io.File;
import java.util.Scanner;
public class Exceptions {
public static void main(String[] args) {
String input, formattedInt, field[];
int recordNumber = 0;
int length;
Scanner inputFile;
try {
inputFile = new Scanner(new File("data.txt"));
while (inputFile.hasNextLine()) {
recordNumber++;
formattedInt = String.format("%2d", recordNumber);
input = inputFile.nextLine();
field = input.split(",");
length = field.length;
if (field.length != 5) throw new CustomException(field.length);
System.out.println("Record #" + formattedInt + ": " + input);
}
} catch (Exception e) {
System.out.println("Error! Problem opening file.\nError was: " + e);
} catch (CustomException ce) {
System.out.println(ce);
}
}
}
CustomException.java
package exceptions;
public class CustomException extends Exception {
private int fieldcount;
public CustomException(int fieldCount) {
super("Invalid Count: " + fieldCount);
}
public int getCount() {
return fieldcount;
}
}
CustomException extends Exception so any CustomException will be caught in the first catch block.
Rearrange your blocks so the catch(CustomException e) block comes before the catch(Exception e) block
From time to time I come across a class where a bigger part of code are logging calls.
e.g.
public init(Config config) {
logger.info("Configuring ...");
if (config.hasInitInterval()) {
initInterval = config.getInitInterval();
logger.info("Set initInterval to " + initInterval);
}
...
try {
logger.info("Updating access points " + config.getAccessPoints());
updateAccessPoints(config.getAccessPoints())
} catch (Throwable e) {
logger.warn("Init failed due to ", e);
}
...
if (logger.isDebugEnabled ()) {
for(int i = 0; i < config.getModifiers().size(); i++) {
try {
isValidModifier(config.getModifiers().get(i));
} catch (Exception e) {
throw new IllegalArgumentException ("Wrong modifier: " config.getModifiers().get(i));
}
}
}
}
When a class is not formatted well plus contains comments, it's hard to read the code.
I used proxy pattern to partially improve it but it's suitable only to log something before or after a call of method.
What are the best practices to separate functionality from logging?
Im confused how throw and catch work,I understand their are several mistakes with this ExceptionDemo. If someone could fix the mistake and clearly state why and how they corrected it without using all the Java jargon words, and use simple terms
Thank you
public class ExceptionDemo {
public static void main( String [] args ) {
try {
int number = Integer.parseInt(”123”);
if (number > 100) {
catch new ArithmeticException(”Check the number”);
}
}
catch {
System.out.println(”Cannot convert to int”);
}
finally (Exception e) {
System.out.println(”Always print”);
}
}
}
a bit tricky to tell exactly what is needed here. for starters looks like as would need to throw an exception if checking for some sort of valid value. also looks like the catch would need to have the exception handler itself not the finally.
//listing 1 slight re-work original post
public class Main {
public static void main(String[] args) throws ArithmeticException {
try {
int number = Integer.parseInt("123");
if (number > 100) {
// is this what trying to do?
//would expect typically would be used to handle
//something like div by zero, etc.
throw new ArithmeticException("Check the number");
}
}
//catch exception(s) here
catch (Exception e) {
System.out.println("Cannot convert to int:" + e.toString());
}
finally {
System.out.println("Always print");
}
}
}
//listing 2 more typical type thing maybe
public class Main {
public static void main(String[] args) {
try {
//int number = Integer.parseInt("A123"); // if un-comment throws generic exception bad input
int number = 100 / 0; //will throw an "arithmetic" exception
//
if (number > 100) {
//do something.
int x = number++;
}
}
catch (ArithmeticException arithEx){
System.out.println("An ArithmeticException Occurred:" + arithEx.toString());
}
catch (Exception e) {
System.out.println("A general exception occurred:" + e.toString());
}
finally {
//always gets executed. so is good place to clean up, close connections etc.
System.out.println("Always print");
}
}
}
In addition to hurricane's answer, you cannot catch a new exception. Instead you need to throw it.
throw new Exception();