【问题标题】:Java Try Catch blockJava Try Catch 块
【发布时间】:2016-05-21 03:58:19
【问题描述】:

我最初在大学开始编程并学习了 vb.net。现在我决定转向 Java 并有一些疑问。在vb中,try catch语句的布局如下

try
Catch ex as exception
finally
End catch

但来自 java 网站 (https://docs.oracle.com/javase/tutorial/essential/exceptions/putItTogether.html) 我发现在java中你使用了两个像这样的catch:

    try {

} catch (ExceptionType name) {

} catch (ExceptionType name) {

}

我希望有人能解释为什么你需要在 java 中使用两个 catch 以及各自的 catch 做什么/catch。

谢谢。

【问题讨论】:

  • 一段代码可能会产生N种异常,你可以为不同的异常定义不同的流程。
  • 这两个捕获不能是相同的异常类型(这将是一个编译时错误) - 它们必须是不同的类型,您希望以不同的方式处理。
  • 你不需要两个。您可以有 1..N 个捕获来捕获不同类型的异常。

标签: java vb.net error-handling try-catch


【解决方案1】:

链接中页面上的代码我已经修改了它,但只有一个例外。这里的问题是,在这种情况下,您将无法知道异常是由于

IndexOutOfBoundsException 或 IOException

只知道发生了异常

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");
            }
        }
    }
}

让我们理解这个概念最好知道为什么代码会由于哪种特定类型的异常而失败

IndexOutOfBoundsException 或 IOException

现在处理不同异常的代码

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");
            }
        }
    }
}

在这里我们可以知道它是否由于在位置创建文件而失败

e://OutFile.txt 驱动器不在我的系统上

错误打印为

Caught Exception: e:\OutFile.txt (系统找不到路径 指定)输入 try 语句 PrintWriter 未打开

下一个案例

现在当我评论这一行时

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");
                }
            }
        }
    }

然后它清楚地说它因索引超出范围异常而失败

进入 try 语句 Caught IndexOutOfBoundsException: Index: 0, 大小:0 关闭 PrintWriter

因此,为了正确有效地调试应用程序,它是好的。

我已经为其他类型的异常创造了条件

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.

【讨论】:

  • 感谢您的回答。
【解决方案2】:

在 Java 中,您可以使用多个 catch 块。

这并不一定意味着您必须这样做。

这取决于您在try 块中拥有的代码,以及它可能会抛出多少已检查的Exceptions(如果您真的想抓住它,甚至是未检查的Exceptions,通常您不会而且您不必必须)。

一种不好的做法是对一般Exception(或更糟的是Throwable,它也会捕获RuntimeExceptions 和Errors)使用单个处理程序:

try {
    // stuff that throws multiple exceptions
}
// bad
catch (Exception e) {
    // TODO
}

好的做法是捕获所有可能抛出的检查 Exceptions。

如果其中一些在继承方面相关,请始终先捕获子类(即更具体的Exceptions),以免您的代码无法编译:

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
}

还可以查看 Java 7 的 multi-catch blocks,其中不相关的 Exceptions 可以在每个 Exception 类型之间使用 | 分隔符一次性捕获:

try (optionally with resources) {
    // stuff that throws FileNotFoundException and MyOwnCheckedException
}
// below exceptions are unrelated
catch (FileNotFoundException | MyOwnCheckedException e) {
    // TODO
}

注意

在您链接到的 this 示例中,将它们放在一起下面的第一个代码 sn-p 可以说是次优的:它确实捕获了可能抛出Exceptions,但其中一个是IndexOutOfBoundsException,它是RuntimeException(未选中),理论上不应处理。

相反,SIZE 变量(或可能的常量)应替换为对正在迭代的List 大小的引用,即list.size(),以防止IndexOutOfBoundsException 被抛出。

我想在这种情况下只是提供一个例子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多