标签: checked-exceptions

Java:已检查vs未经检查的异常说明

我已经在StackOverFlow上阅读了有关已检查和未经检查的异常的多个帖子.老实说,我还是不太确定如何正确使用它们.

Joshua Bloch在" Effective Java "中说过

对可恢复条件使用已检查的异常,对编程错误使用运行时异常(第2版中的第58项)

让我们看看我是否正确理解这一点.

以下是我对已检查异常的理解:

try{
    String userInput = //read in user input
    Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
    id = 0; //recover the situation by setting the id to 0
}
Run Code Online (Sandbox Code Playgroud)

1.以上是否考虑了检查异常?

2. RuntimeException是未经检查的异常吗?

以下是我对未经检查的异常的理解:

try{
    File file = new File("my/file/path");
    FileInputStream fis = new FileInputStream(file);   
}catch(FileNotFoundException e){

//3. What should I do here?
    //Should I "throw new FileNotFoundException("File not found");"?
    //Should I log?
    //Or should I System.exit(0);?
}
Run Code Online (Sandbox Code Playgroud)

4.现在,上述代码也不能成为检查异常吗?我可以尝试恢复这样的情况吗?我可以吗?(注意:我的第3个问题在catch上面)

try{
    String …
Run Code Online (Sandbox Code Playgroud)

java exception runtimeexception checked-exceptions unchecked-exception

678
推荐指数
11
解决办法
31万
查看次数

针对已检查异常的案例

多年来,我一直无法得到以下问题的正确答案:为什么一些开发人员如此反对已检查的异常?我有很多对话,在博客上阅读,阅读Bruce Eckel所说的内容(我看到的第一个人反对他们).

我目前正在编写一些新代码,并非常注意我如何处理异常.我试图看到"我们不喜欢被检查的例外"人群的观点,我仍然看不到它.

每次谈话结束时,同样的问题都没有得到答复......让我把它设置起来:

一般来说(从Java的设计方式来看),

  • 对于永远不应该捕获的东西是错误的(VM有花生过敏而且有人丢了一罐花生)
  • RuntimeException用于程序员做错的事情(程序员走出数组的末尾)
  • 异常(RuntimeException除外)适用于程序员无法控制的内容(在写入文件系统时磁盘已填满,已达到进程的文件句柄限制,您无法再打开任何文件)
  • Throwable只是所有异常类型的父级.

我听到的一个常见论点是,如果发生异常,那么开发人员将要做的就是退出该程序.

我听到的另一个常见论点是,经过检查的异常会使重构代码变得更加困难.

对于"我将要做的就是退出"这个论点,我说即使你要退出,你也需要显示一个合理的错误信息.如果您只是在处理错误,那么当程序退出而没有明确说明原因时,您的用户将不会过于高兴.

对于"它很难重构"的人群,这表明没有选择适当的抽象级别.而不是声明方法抛出IOException,IOException应该转换为更适合正在发生的事件的异常.

我没有使用catch(Exception)包装Main的问题(或者在某些情况下catch(Throwable)以确保程序可以正常退出 - 但我总是捕获我需要的特定异常.这样做允许我,至少,显示适当的错误消息.

人们从不回复的问题是:

如果你抛出RuntimeException子类而不是Exception子类,那么你怎么知道你应该捕获什么?

如果答案是捕获异常,那么您也会以与系统异常相同的方式处理程序员错误.这对我来说似乎不对.

如果您捕获Throwable,那么您将以相同的方式处理系统异常和VM错误(等).这对我来说似乎不对.

如果答案是你只捕获你知道的异常,那么你怎么知道抛出的是什么?当程序员X抛出一个新的异常并忘记捕获它时会发生什么?这对我来说似乎非常危险.

我会说显示堆栈跟踪的程序是错误的.那些不喜欢检查异常的人是不是觉得那样?

那么,如果您不喜欢已检查的异常,您可以解释为什么不能并且回答那些无法解答的问题吗?

编辑:我不是在寻找何时使用任何一个模型的建议,我正在寻找的是为什么人们从RuntimeException扩展,因为他们不喜欢从Exception扩展和/或为什么他们捕获异常然后重新抛出RuntimeException而不是将抛出添加到他们的方法中.我想了解不喜欢检查异常的动机.

java exception checked-exceptions

437
推荐指数
21
解决办法
5万
查看次数

如何从Java 8流中抛出CHECKED异常?

如何从Java 8流/ lambdas中抛出CHECKED异常?

换句话说,我想像这样编译代码:

public List<Class> getClasses() throws ClassNotFoundException {     

    List<Class> classes = 
        Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
              .map(className -> Class.forName(className))
              .collect(Collectors.toList());                  
    return classes;
    }
Run Code Online (Sandbox Code Playgroud)

此代码无法编译,因为Class.forName()上面的方法抛出ClassNotFoundException,检查.

请注意我不希望将已检查的异常包装在运行时异常中,而是抛出包装的未经检查的异常.我想抛出已检查的异常本身,而不是向流添加丑陋的try/ catches.

java lambda checked-exceptions java-8 java-stream

270
推荐指数
10
解决办法
11万
查看次数

何时选择已检查和未检查的例外

在Java(或任何其他具有已检查异常的语言)中,在创建自己的异常类时,如何确定是应该选中还是取消选中它?

我的直觉是,如果调用者能够以某种富有成效的方式恢复,那么将调用一个已检查的异常,其中未经检查的异常对于不可恢复的情况更多,但我会对其他人的想法感兴趣.

java exception checked-exceptions

197
推荐指数
10
解决办法
5万
查看次数

调用函数时为什么需要"抛出异常"?

class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器报告方法show2(),show3()以及main()具有

未报告的异常必须捕获​​或声明要抛出的异常

当我throws Exception从这些方法中删除?

java exception-handling unhandled-exception throws checked-exceptions

90
推荐指数
3
解决办法
18万
查看次数

Java 8:在lambda表达式中强制检查异常处理.为什么强制,不是可选的?

我正在使用Java 8中的新lambda特性,并发现Java 8提供的实践非常有用.但是,我想知道是否有一种很好的方法可以解决以下情况.假设您有一个对象池包装器,需要某种工厂来填充对象池,例如(使用java.lang.functions.Factory):

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public ConnectionPool(int maxConnections, String url) {
        super(new Factory<Connection>() {
            @Override
            public Connection make() {
                try {
                    return DriverManager.getConnection(url);
                } catch ( SQLException ex ) {
                    throw new RuntimeException(ex);
                }
            }
        }, maxConnections);
    }

}
Run Code Online (Sandbox Code Playgroud)

将函数接口转换为lambda表达式后,上面的代码变为:

public class JdbcConnectionPool extends ObjectPool<Connection> {

    public ConnectionPool(int maxConnections, String url) {
        super(() -> {
            try {
                return DriverManager.getConnection(url);
            } catch ( SQLException ex ) {
                throw new RuntimeException(ex);
            }
        }, maxConnections); …
Run Code Online (Sandbox Code Playgroud)

java lambda checked-exceptions java-8

69
推荐指数
4
解决办法
4万
查看次数

为什么捕获检查的异常允许不抛出异常的代码?

在Java中,抛出已检查异常的方法(异常或其子类型 - IOException,InterruptedException等)必须声明throws语句:

public abstract int read() throws IOException;
Run Code Online (Sandbox Code Playgroud)

不声明throws语句的方法不能抛出已检查的异常.

public int read() { // does not compile
    throw new IOException();
}
// Error: unreported exception java.io.IOException; must be caught or declared to be thrown
Run Code Online (Sandbox Code Playgroud)

但是在安全方法中捕获已检查的异常在java中仍然是合法的:

public void safeMethod() { System.out.println("I'm safe"); }

public void test() { // method guarantees not to throw checked exceptions
    try {
        safeMethod();
    } catch (Exception e) { // catching checked exception java.lang.Exception
        throw e; …
Run Code Online (Sandbox Code Playgroud)

java exception try-catch checked-exceptions unchecked-exception

34
推荐指数
3
解决办法
5247
查看次数

将已检查的异常包装到Java中未经检查的异常中?

我在java中有这个工厂方法:

public static Properties getConfigFactory() throws ClassNotFoundException, IOException {
    if (config == null) {
        InputStream in = Class.forName(PACKAGE_NAME).getResourceAsStream(CONFIG_PROP);
        config = new Properties();
        config.load(in);
    }
    return config;
}
Run Code Online (Sandbox Code Playgroud)

我想将两个已检查的异常转换为未经检查的异常.最好的方法是什么?

我应该捕获异常并使用捕获的异常作为内部异常抛出一个新的RuntimeException吗?

有没有更好的方法来做到这一点,或者我是否应该首先尝试这样做?

编辑:
只是为了澄清.这些异常将是致命的,因为配置文件基本上是程序的操作,所有异常都将被捕获并记录在我的程序的顶层.

我的目的是避免不必要的抛出异常,将异常添加到调用我的工厂的每个方法的签名中.

java exception checked-exceptions

29
推荐指数
2
解决办法
3万
查看次数

JLS的哪些部分证明能够抛出已检查的异常,就好像它们未经检查一样?

最近发现并写了一篇关于这样一个事实的博客:有可能通过javac编译器偷看一个已检查的异常,并将它扔到不能抛出它的地方.这在Java 6和7中编译并运行,抛出一个SQLExceptionwithout throwscatch子句:

public class Test {

    // No throws clause here
    public static void main(String[] args) {
        doThrow(new SQLException());
    }

    static void doThrow(Exception e) {
        Test.<RuntimeException> doThrow0(e);
    }

    static <E extends Exception> void doThrow0(Exception e) throws E {
        throw (E) e;
    }
}
Run Code Online (Sandbox Code Playgroud)

生成的字节码表示JVM并不真正关心已检查/未检查的异常:

// Method descriptor #22 (Ljava/lang/Exception;)V
// Stack: 1, Locals: 1
static void doThrow(java.lang.Exception e);
  0  aload_0 [e]
  1  invokestatic Test.doThrow0(java.lang.Exception) : void [25]
  4  return
    Line numbers:
      [pc: …
Run Code Online (Sandbox Code Playgroud)

java generics exception jls checked-exceptions

29
推荐指数
2
解决办法
4477
查看次数

如何包装已检查的异常但在Java中保留原始运行时异常

我有一些代码可能会抛出已检查和运行时异常.

我想捕获已检查的异常并将其包装为运行时异常.但是如果抛出RuntimeException,我不必将它包装起来,因为它已经是运行时异常.

我的解决方案有点开销,并不"整洁":

try {
  // some code that can throw both checked and runtime exception
} catch (RuntimeException e) {
  throw e;
} catch (Exception e) {
  throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)

想要更优雅的方式吗?

java runtimeexception checked-exceptions

25
推荐指数
3
解决办法
6640
查看次数