Java接口抛出异常但接口实现不会引发异常?

Al2*_*2O3 44 java interface exception

我读了这个代码,其中接口抛出异常,但实现它的类不会抛出一个或捕获一个,为什么会这样?在java中它是合法的还是安全的?

import java.rmi.*;
public interface MyRemote extends Remote {
    public String sayHello() throws RemoteException;
}

import java.rmi.*;
import java.rmi.server.*;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{
    public String sayHello() {
        return "Server says, 'Hey'";
    }
    public MyRemoteImpl() throws RemoteException {}
    public static void main (String[] args) {
        try {
             MyRemote service = new MyRemoteImpl();
             Naming.rebind("RemoteHello", service);
        } catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Che*_*min 72

实现和扩展的一般规则是,您可以使新的类或接口"限制性更小",但不能"限制性更强".如果您考虑将异常作为限制处理的要求,则不声明该异常的实现限制较少.任何编码到界面的人都不会遇到你班级的问题.

- 斯坦詹姆斯


作为http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface讨论的一部分


Eri*_*low 17

如果Java方法覆盖父类中的另一个方法,或实现接口中定义的方法,则它可能不会抛出其他已检查的异常,但可能会抛出更少的异常.

public class A {
    public void thrower() throws SQLException {...}
}

public class B extends A {
    @Override
    public void thrower() throws SQLException, RuntimeException, NamingException {...}
}
Run Code Online (Sandbox Code Playgroud)

SQLException很好; 它是在重写方法中声明的.它甚至可以被类似的子类所取代SerialException.

RuntimeException很好; 那些可以在任何地方使用.

NamingException是非法的.即使作为子类型,它也不是RuntimeException,也不在A列表中.


Foo*_*ish 8

@Chetter Hummin 的精彩回答。

看待这一点的一种方式,我发现它很容易记住,是接口的实现可以更具体但不是更通用。

例如在接口中void test() throws Exception意味着“测试可能会抛出异常”

那么实现可能void test()意味着“测试不会抛出异常”(更具体)

或实现可以void test() throws NullpointerException(更具体)

interface x {
    void testException() throws Exception;
}

public class ExceptionTest implements x {
    @Override
    public void testException() {   //this is fine
    }

    ////// or

    @Override
    public void testException() throws NullPointerException {  // this is fine
    }
}
Run Code Online (Sandbox Code Playgroud)