Java是否声明;抛出异常“;默认情况下?

Java是否声明;抛出异常“;默认情况下?,java,exception,exception-handling,Java,Exception,Exception Handling,考虑以下类别: class X { public void met() { } } 及 从我读到的其他问题(和) 我理解子类中的重写方法必须抛出与被重写方法中抛出的异常相同的子类或子类 Java方法是否总是至少抛出异常类型的异常? …换句话说,编译器添加抛出异常 那么类X看起来像这样 class X { public void met() throws Exception { } } 我想澄清一点,我没有误解始终添加默认异常处理程序异常这一事实 相关问题: 有两

考虑以下类别:

class X
{
public void met()
   {
   }
}

从我读到的其他问题(和)

我理解子类中的重写方法必须抛出与被重写方法中抛出的异常相同的子类或子类

Java方法是否总是至少抛出异常类型的异常?

…换句话说,编译器添加抛出异常

那么类X看起来像这样

class X {
    public void met() throws Exception {

    }
}
我想澄清一点,我没有误解始终添加默认异常处理程序异常这一事实

相关问题:


有两种类型的异常:检查异常(如解析文本时的
ParseException
)和未检查异常(如
NullPointerException

选中的异常必须在方法签名中声明。未经检查的异常可以在方法签名中声明

重写方法(从接口或超类)时,只需指定在实现中抛出的异常。不能声明在重写方法中不允许的实现中引发选中的异常

这是允许的:

class X { void someMethod() }
class Y extends X { @Override void someMethod() throws UncheckedException }
这是不允许的:

class X { void someMethod() }
class Y extends X { @Override void someMethod() throws CheckedException }
这也是允许的:

class X { void someMethod() throws CheckedException }
class Y extends X { @Override void someMethod() }
我在信中所说的完全正确。再解释一下:

如果要在方法体内部抛出,则需要处理它(使用catch块)或声明
throws子句

重申先前链接的JLS:

  • 例外情况是类扩展了可丢弃的
  • 一个错误也是一个类扩展
    可丢弃
    • 错误通常不应被发现,因为它们表明存在严重问题。(例如,
      OutOfMemoryError
    • 捕获
      异常
      不会捕获错误
  • 还有
    RuntimeException
    。这是一个扩展异常的类
  • 错误和运行时异常在编译时不被检查,因为这正是“检查的异常”的意思

    您可以在代码中的任何位置抛出
    Error
    s和
    RuntimeException
    s

    现在,这将如何影响以下条款:

    throws子句指定调用声明的方法可能导致指定的异常。有趣的是,throws需要一个可丢弃的
    ,这使得以下声明有效:

    public void method() throws StackOverflowError, NullPointerException {
        //...
    }
    
    在throws子句中声明未检查的异常时,编译器不会起作用,但有时这样做是为了使源代码更加清晰

    此外,JavaDoc中有时会提到此类例外情况(例如:

    但是编译器在重写方法时检查throws子句。这与重写方法时的可见性规则有些相似。这意味着总是可以抛出未检查的异常(并声明相应的抛出子句)。以下声明有效:

    public interface Demo {
        void test();
    }
    public class DemoImpl implements Demo {
        public void test() throws NullPointerException {
            throw new NullPointerException();
        }
    }
    
    public interface Demo {
        void test() throws IOException, ParseException;
    }
    public class DemoImpl implements Demo {
        public void test() throws IOException {
            throw new IOException();
        }
    }
    
    反过来也是一样的。编译器将忽略throws子句中未检查的异常,因为它们与编译时检查无关:

    public interface Demo {
        void test() throws NullPointerException;
    }
    public class DemoImpl implements Demo {
        public void test() {
            throw new NullPointerException();
        }
    }
    
    throws子句继承的一般规则是:一个接口来控制它们:该接口必须声明可以通过实现类抛出的所有已检查异常。换句话说:

    实现类可以在实现方法的throws子句中接口方法的throws子句中声明声明的已检查异常的子集

    这意味着以下内容有效:

    public interface Demo {
        void test();
    }
    public class DemoImpl implements Demo {
        public void test() throws NullPointerException {
            throw new NullPointerException();
        }
    }
    
    public interface Demo {
        void test() throws IOException, ParseException;
    }
    public class DemoImpl implements Demo {
        public void test() throws IOException {
            throw new IOException();
        }
    }
    
    无效的是在实现方法的throws子句中声明一个在相应接口方法的子句中未声明的已检查异常:

    public interface Fail {
        void test() throws ParseException;
    }
    public class FailImpl implements Fail {
        public void test() throws IOException {
            throw new IOException();
        }
    }
    

    不。没有。请注意,除非您有特定的理由(通过抛出异常)将异常传播到调用方层次结构,否则您可能应该使用catch块(或
    try with resources
    )来处理异常
    NullPointerException
    是一个
    RuntimeException
    并且不需要
    抛出
    子句。唯一不需要声明的异常类型是
    RuntimeException
    和扩展它的异常。好吧,为什么编译器在重写met方法时不抱怨?在super的方法中,我不会抛出任何异常。签名在子类中已更改。首先,
    不能引发异常。代码示例有助于理解其工作原理。我以前做过一个练习,当被重写的方法根本没有抛出任何东西时,重写方法抛出了CheckedException(IOException)。现在我明白为什么了。谢谢。一个代码示例比许多理论文章都好^ ^ ^对答案进行了很好的阐述,并且是更多阅读该问题的好来源,尤其是关于检查和未检查的异常。我不知道编译时会忽略未检查的异常。谢谢