Exception Java API是否违反了Liskov原则?

时间:2014-09-15 03:32:29

标签: java oop exception solid-principles

根据java.lang.Exception层次结构:     enter image description here

并且给定Liskov替换原则: ...如果S是T的子类型,则类型T的对象可以替换为S类型的对象...

对于子类(Checked vs Unchecked)我们有两种不同的行为,并且在某些情况下我们无法有效地用子类对象替换基类使用,除非我们更改当前代码,例如,如果我们编写类似的代码:

try{
     InputStream is = new FileInputStream("C://test.txt");//throws IOException                        
     while((i=is.read())!=-1){
        c=(char)i;            
        System.out.print(c);
     }
  }catch(Exception e){// can not be replaced by any subtype, but IOException
     e.printStackTrace();
  }

这是违规吗?为什么/为什么不呢?。

来源:http://www.oracle.com/technetwork/articles/entarch/effective-exceptions-092345.html

编辑1

示例2:

鉴于方法:

public class MyClass {
    public void test() throws Exception{
        // nice stuff
    }
}

客户:

public class MyTest {

    MyClass clazz = new MyClass();

    // 'Exception' can not be changed by a subclass directly
    public void testTest() throws Exception { 
        clazz.test();
    }
}

编辑2

你告诉我,我可以创建一个子类并覆盖该方法而不抛出异常,这是完全有效的,但不是我想要告诉你的。

当我说'异常'不能直接由子类改变,我的意思是:你不能写出类似的东西:

// You can not do this at home
public class MyTest {

    MyClass clazz = new MyClass();

    // hey look!, there is a compiler error!
    public void testTest() throws NullPointerException { 
        clazz.test();
    }
}

1 个答案:

答案 0 :(得分:4)

LSP意味着您可以在任何需要基类实例的地方使用任何子类实例。并不是说您可以在代码中随意更改类名称,就像在' catch'例。否则,OO程序将是不可写的。

你的第二个例子仅仅是错误的。 '抛出异常' 可以替换为Exception的任何子类。并不是说它是LSP的一个例子。