Java:如何重写方法并引发异常?

Java:如何重写方法并引发异常?,java,exception,overriding,Java,Exception,Overriding,我试图重写一个方法,但引发了一个异常: class A { public doSomething(){ // some of logic } } class B extends A { public doSomething() throws MyCustomizedException { try { // some of logic } catch(ExceptionX ex ) {

我试图重写一个方法,但引发了一个异常:

class A {

    public doSomething(){
        // some of logic
    }

}


class B extends A {

    public doSomething() throws MyCustomizedException {
        try {
             // some of logic
        } catch(ExceptionX ex ) {
             throw new MyCustomizedException(" Some info ", ex);
        }
    }      
}
但是我得到了这个编译时错误:

Exception MyCustomizedException is not compatible with throws clause in A
这两个限制是:

  • 使用相同的函数名和参数(如果存在):doSomething()
  • 正在抛出自定义异常
我怎样才能排除异常


非常感谢。

这不是一个超载的案例。要重载,您需要具有相同签名但参数列表不同的方法。这是重写,如果类A可以修改,则使用
public doSomething()在类A中抛出MyCustomizedException{}


现在可以使用类B的当前实现进行重写。

这不是重载情况。要重载,您需要具有相同签名但参数列表不同的方法。这是重写,如果类A可以修改,则使用
public doSomething()在类A中抛出MyCustomizedException{}

现在,您可以使用类B的当前实现进行重写。

无法完成

重写方法时,不能破坏原始约定并决定抛出选中的异常

您可以取消选中
MyCustomizedException
。您可以抛出它,但不能要求用户以您可以使用选中异常的方式处理它。您所能做的最好的事情就是将其添加到javadocs并进行解释。

无法完成

重写方法时,不能破坏原始约定并决定抛出选中的异常


您可以取消选中
MyCustomizedException
。您可以抛出它,但不能要求用户以您可以使用选中异常的方式处理它。最好的方法是将它添加到javadocs中并进行解释。

唯一的方法是将抛出的异常设置为extend RuntimeException,而不是exception


这样你就可以在不改变方法紧凑性的情况下抛出它,不幸的是,编译器不会自动检测到您需要捕获该异常,但这取决于您使用该异常的方式,这可能不是问题。

唯一的方法是使异常成为您正在引发的extend RuntimeException而不是exception


这样,您就可以在不更改方法的紧凑性的情况下抛出它,不幸的是,编译器不会自动检测到您需要捕获该异常,但这取决于您如何使用它,这可能不是问题。

实际上有一种方法可以做到这一点-使用组合而不是继承:

class B {
   A a = new A();
   void doSomething() throws MyException {
      a.doSomething();
      throw MyException();
   }
}

当然,通过这样做,您的B不再算作A,因此无法传递给任何需要A的对象。不过,您可以在整个代码中使用B,并按需包装。

实际上有一种方法可以做到这一点-使用组合而不是继承:

class B {
   A a = new A();
   void doSomething() throws MyException {
      a.doSomething();
      throw MyException();
   }
}


当然,通过这样做,您的B不再算作A,因此无法传递给任何需要A的对象。不过,您可以在整个代码中使用B,并按需包装。

只有在类A是his且可以修改的情况下才可能。如果是第三方库,则不起作用。只有在类a是他的并且可以修改时才可能。如果是第三方图书馆就不起作用。可能是你的复制品,我会投反对票。完全没有以前研究的证据。您没有试图重载一个方法(同名的多个方法签名),而是试图重写一个方法。但似乎不允许通过引发异常来重载。只允许添加参数或更改其类型。。。对吧?可能是你的复制品可能是你的复制品我投了反对票。完全没有以前研究的证据。您没有试图重载一个方法(同名的多个方法签名),而是试图重写一个方法。但似乎不允许通过引发异常来重载。只允许添加参数或更改其类型。。。对吗?这可能的重复项不是重载。反之亦然。这不是重载。反之亦然。应该检查我的自定义异常。它扩展了异常…:/我刚刚发布了一个新的答案。如果这对你不起作用,那么你就别无选择。我的自定义异常应该被检查。它扩展了异常…:/我刚刚发布了一个新的答案。如果这对你不起作用,那么你就别无选择。你失去了IS-A和多态性。利斯科夫替换原则不会让你在任何有a的地方使用B。事实上,我的回答在最后一句中是这样说的。如果OP不需要B算作A(这可能取决于他们对库所做的事情、A和B是什么等),那么它就解决了问题。接口是保持可替换性的一种方法。使用
接口DoerOfThings{void doSomething();}
,类
A
B
都可以实现
DoerOfThings
B
甚至可以使用
A
通过组合实现接口。当然,接口的成员越多,
B
必须包含的样板文件越多,才能重用
A
的实现。您丢失了IS-A和多态性。利斯科夫替换原则不会让你在任何有a的地方使用B。事实上,我的回答在最后一句中是这样说的。如果OP不需要B算作A(这可能取决于他们对库所做的事情、A和B是什么等),那么它就解决了问题。接口是保持可替换性的一种方法。使用
接口DoerOfThings{void doSomething();}
,类
A
B
都可以实现
DoerOfThings
B
甚至可以使用
A
通过组合实现接口。当然,接口的成员越多,
B
必须包含的样板文件就越多,才能重用
A
的i