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

时间:2021-10-16 11:40:34

I read this code where the interface throws an exception, but the class which implements it doesn't throw one or catch one, why is that? Is it legal or safe in java?

我读了这个代码,其中接口抛出异常,但实现它的类不会抛出一个或捕获一个,为什么会这样?它在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();
        }
    }
}

3 个解决方案

#1


52  

A general rule of implementing and extending is you can make your new class or interface "less restrictive" but not "more restrictive". If you think of the requirement to handle an exception as a restriction, an implementation that doesn't declare the exception is less restrictive. Anybody who codes to the interface will not have trouble with your class.

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

— Stan James

- 斯坦詹姆斯


As part of the discussion at http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface

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

#2


12  

If a Java method overrides another in a parent class, or implements a method defined in an interface, it may not throw additional checked exceptions, but it may throw fewer.

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

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

public class B extends A {
    @Override
    public void thrower() throws SQLException, RuntimeException, NamingException {...}
}

SQLException is fine; it's declared in the overridden method. It could even be replaced by a subclass like SerialException.

SQLException很好;它是在重写方法中声明的。它甚至可以被像SerialException这样的子类替换。

RuntimeException is fine; those can be used anywhere.

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

NamingException is illegal. It isn't a RuntimeException, and isn't in A's list, even as a subtype.

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

#3


0  

Great answer by @Chetter Hummin.

@Chetter Hummin的精彩回答。

One way to look at this, and I find it easy to remember, is interface's implementations can be more specific but not more general.

一种看待这个问题的方法,我觉得很容易记住,接口的实现可以更具体,但不是更通用。

For example in interface void test() throws Exception means "test may throw exception"

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

then implementation can be void test() means "test will not throw exception" (more specific)

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

or implementation can be void test() throws NullpointerException (more specific)

或者实现可以是void test()抛出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
    }
}

#1


52  

A general rule of implementing and extending is you can make your new class or interface "less restrictive" but not "more restrictive". If you think of the requirement to handle an exception as a restriction, an implementation that doesn't declare the exception is less restrictive. Anybody who codes to the interface will not have trouble with your class.

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

— Stan James

- 斯坦詹姆斯


As part of the discussion at http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface

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

#2


12  

If a Java method overrides another in a parent class, or implements a method defined in an interface, it may not throw additional checked exceptions, but it may throw fewer.

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

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

public class B extends A {
    @Override
    public void thrower() throws SQLException, RuntimeException, NamingException {...}
}

SQLException is fine; it's declared in the overridden method. It could even be replaced by a subclass like SerialException.

SQLException很好;它是在重写方法中声明的。它甚至可以被像SerialException这样的子类替换。

RuntimeException is fine; those can be used anywhere.

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

NamingException is illegal. It isn't a RuntimeException, and isn't in A's list, even as a subtype.

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

#3


0  

Great answer by @Chetter Hummin.

@Chetter Hummin的精彩回答。

One way to look at this, and I find it easy to remember, is interface's implementations can be more specific but not more general.

一种看待这个问题的方法,我觉得很容易记住,接口的实现可以更具体,但不是更通用。

For example in interface void test() throws Exception means "test may throw exception"

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

then implementation can be void test() means "test will not throw exception" (more specific)

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

or implementation can be void test() throws NullpointerException (more specific)

或者实现可以是void test()抛出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
    }
}