Java Try Catch block

2019-02-24 11:02发布

问题:

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.

回答1:

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.



回答2:

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.