Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我们总是要抛出新的异常?我们不能将该异常存储为实例变量并每次抛出相同的实例吗?_Java_Exception_Error Handling - Fatal编程技术网

Java 为什么我们总是要抛出新的异常?我们不能将该异常存储为实例变量并每次抛出相同的实例吗?

Java 为什么我们总是要抛出新的异常?我们不能将该异常存储为实例变量并每次抛出相同的实例吗?,java,exception,error-handling,Java,Exception,Error Handling,在java中,到目前为止我所看到的是,每当我们抛出异常时,我们都会抛出新的异常。就像下面的例子 try{ somethingThatCanGoWrong(); }catch(Exception e){ throw new FailedToDoSomethingException("The other guy failed"); } 是否总是需要抛出异常的新实例? 我可以用下面的方法吗 public class Blah { private static final Fa

在java中,到目前为止我所看到的是,每当我们抛出异常时,我们都会抛出新的异常。就像下面的例子

try{
    somethingThatCanGoWrong();
}catch(Exception e){
    throw new FailedToDoSomethingException("The other guy failed");
}
是否总是需要抛出异常的新实例? 我可以用下面的方法吗

public class Blah
{
    private static final FailedToDoSomethingException failedToDoSomethingException = new FailedToDoSomethingException(
        "The other guy failed" );

    public static void main( String[] args )
    {
        try {
            somethingThatCanGoWrong();
        } catch ( Exception e ) {
            throw failedToDoSomethingException;
        }
    }
}
我不喜欢最后一个例子,因为有两个原因

  • 从面向对象的角度讲,任何异常既不是类的属性,也不是实例的属性
  • 当异常消息是动态生成的并且基于方法参数时,在多线程环境中会失败。下面是一个例子

    File-getFile(字符串文件路径){

    抛出新的FileNotFoundException(“未找到路径为“+filePath+”的文件”);

    }

  • 除了以上两个原因,还有其他原因吗?当我们创建一个异常的新实例时,在幕后会发生什么?比如填充异常上下文(比如stacktrace。但是我相信当我们使用
    throw
    关键字时会发生这种情况)


    还是一直抛出一个新异常只是一种好的做法?(再说一遍,为什么这是一种好的做法?

    stacktrace显示了创建异常时的行,因此您无法真正看到抛出异常的位置

    您可以执行以下示例:

    public class Foo {
    
        private static final RuntimeException re = new RuntimeException("MSG");
    
        public static void main(String[] args) {
            try {
                Integer.parseInt("!!#!");
            } catch (Exception e) {
                throw re;
            }
        }
    }
    
    当您查看stacktrace时:

    Exception in thread "main" java.lang.RuntimeException: MSG
        at test.Foo.<clinit>(Foo.java:5)
    
    线程“main”java.lang.RuntimeException中的异常:MSG 在test.Foo.(Foo.java:5)
    您可以看到stacktrace中的行不是您实际抛出异常的行,而是您调用的
    new

    异常是特定于上下文的。想想
    printStackTrace()
    。您想查看过去某个时间存储的某个异常的堆栈跟踪,还是想查看引发当前异常的原因?如果您没有抛出新异常,我所能做的就是祝您在调试过程中好运。“最佳实践”并不是因为有人这么说才是最好的——它们是最好的,因为它们为您提供了最佳的结果。这正是我的问题之一。所以当你创建一个
    新的
    验证时,上下文被填充,而不是当你
    抛出它时?不确定你在这里得到了什么。。。原因设定在创建时。您是否希望异常的原因在创建和抛出之间发生变化?是否有可能是您试图回答的一些潜在问题导致您提出这个问题?您希望通过创建和重用异常获得什么?我现在明白了。一个简单的实验帮助我理解了这一点。我有一个错误的想法,即当我们抛出异常时,会生成类似stacktrace的异常上下文。按字面意思使用
    throw
    关键字。但事实证明,所有类似stacktrace的上下文都是在创建异常实例时生成的。