我读了这个代码,其中接口抛出异常,但是实现它的类不会抛出一个或捕获一个,为什么呢?在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();
}
}
}
答案 0 :(得分:66)
实施和扩展的一般规则是,您可以使新的类或界面“限制性更小”,但不能“限制性更强”。如果您考虑将异常作为限制处理的要求,则不声明该异常的实现限制较少。任何编码到界面的人都不会遇到你班级的问题。
- Stan James
作为http://www.coderanch.com/t/399874/java/java/Methods-throwing-Exception-Interface
讨论的一部分答案 1 :(得分:14)
如果Java方法覆盖了父类中的另一个方法,或者实现了接口中定义的方法,它可能不会抛出额外的已检查异常,但可能会抛出更少的异常。
public class A {
public void thrower() throws SQLException {...}
}
public class B extends A {
@Override
public void thrower() throws SQLException, RuntimeException, NamingException {...}
}
SQLException
没问题;它是在重写方法中声明的。甚至可以用像SerialException
这样的子类替换它。
RuntimeException
没问题;那些可以在任何地方使用。
NamingException
是非法的。它不是RuntimeException
,也不在A
的列表中,即使是作为子类型。
答案 2 :(得分:1)
@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
}
}