java违例的限制

覆盖一个方法时,只能产生已在方法的基础类版本中定义的违例。这是一个重要的限制,因为它意味着与基础类协同工作的代码也会自动应用于从基础类衍生的任何对象(当然,这属于基本的OOP概念),其中包括违例。
下面这个例子演示了强加在违例身上的限制类型(在编译期):
 

//: StormyInning.java
// Overridden methods may throw only the
// exceptions specified in their base-class
// versions, or exceptions derived from the
// base-class exceptions.

class BaseballException extends Exception {}
class Foul extends BaseballException {}
class Strike extends BaseballException {}

abstract class Inning {
  Inning() throws BaseballException {}
  void event () throws BaseballException {
   // Doesn't actually have to throw anything
  }
  abstract void atBat() throws Strike, Foul;
  void walk() {} // Throws nothing
}

class StormException extends Exception {}
class RainedOut extends StormException {}
class PopFoul extends Foul {}

interface Storm {
  void event() throws RainedOut;
  void rainHard() throws RainedOut;
}

public class StormyInning extends Inning
    implements Storm {
  // OK to add new exceptions for constructors,
  // but you must deal with the base constructor
  // exceptions:
  StormyInning() throws RainedOut,
    BaseballException {}
  StormyInning(String s) throws Foul,
    BaseballException {}
  // Regular methods must conform to base class:
//! void walk() throws PopFoul {} //Compile error
  // Interface CANNOT add exceptions to existing
  // methods from the base class:
//! public void event() throws RainedOut {}
  // If the method doesn't already exist in the
  // base class, the exception is OK:
  public void rainHard() throws RainedOut {}
  // You can choose to not throw any exceptions,
  // even if base version does:
  public void event() {}
  // Overridden methods can throw
  // inherited exceptions:
  void atBat() throws PopFoul {}
  public static void main(String[] args) {
    try {
      StormyInning si = new StormyInning();
      si.atBat();
    } catch(PopFoul e) {
    } catch(RainedOut e) {
    } catch(BaseballException e) {}
    // Strike not thrown in derived version.
    try {
      // What happens if you upcast?
      Inning i = new StormyInning();
      i.atBat();
      // You must catch the exceptions from the
      // base-class version of the method:
    } catch(Strike e) {
    } catch(Foul e) {
    } catch(RainedOut e) {
    } catch(BaseballException e) {}
  }
} ///:~

在Inning中,可以看到无论构建器还是event()方法都指出自己会“掷”出一个违例,但它们实际上没有那样做。这是合法的,因为它允许我们强迫用户捕获可能在覆盖过的event()版本里添加的任何违例。同样的道理也适用于abstract方法,就象在atBat()里展示的那样。
“interface Storm”非常有趣,因为它包含了在Incoming中定义的一个方法——event(),以及不是在其中定义的一个方法。这两个方法都会“掷”出一个新的违例类型:RainedOut。当执行到“StormyInning extends”和“implements Storm”的时候,可以看到Storm中的event()方法不能改变Inning中的event()的违例接口。同样地,这种设计是十分合理的;否则的话,当我们操作基础类时,便根本无法知道自己捕获的是否正确的东西。当然,假如interface中定义的一个方法不在基础类里,比如rainHard(),它产生违例时就没什么问题。
对违例的限制并不适用于构建器。在StormyInning中,我们可看到一个构建器能够“掷”出它希望的任何东西,无论基础类构建器“掷”出什么。然而,由于必须坚持按某种方式调用基础类构建器(在这里,会自动调用默认构建器),所以衍生类构建器必须在自己的违例规范中声明所有基础类构建器违例。
StormyInning.walk()不会编译的原因是它“掷”出了一个违例,而Inning.walk()却不会“掷”出。若允许这种情况发生,就可让自己的代码调用Inning.walk(),而且它不必控制任何违例。但在以后替换从Inning衍生的一个类的对象时,违例就会“掷”出,造成代码执行的中断。通过强迫衍生类方法遵守基础类方法的违例规范,对象的替换可保持连贯性。
覆盖过的event()方法向我们显示出一个方法的衍生类版本可以不产生任何违例——即便基础类版本要产生违例。同样地,这样做是必要的,因为它不会中断那些已假定基础类版本会产生违例的代码。差不多的道理亦适用于atBat(),它会“掷”出PopFoul——从Foul衍生出来的一个违例,而Foul违例是由atBat()的基础类版本产生的。这样一来,假如有人在自己的代码里操作Inning,同时调用了atBat(),就必须捕获Foul违例。由于PopFoul是从Foul衍生的,所以违例控制器(模块)也会捕获PopFoul。
最后一个有趣的地方在main()内部。在这个地方,假如我们明确操作一个StormyInning对象,编译器就会强迫我们只捕获特定于那个类的违例。但假如我们上溯造型到基础类型,编译器就会强迫我们捕获针对基础类的违例。通过所有这些限制,违例控制代码的“健壮”程度获得了大幅度改善(注释③)。

③:ANSI/ISO C++施加了类似的限制,要求衍生方法违例与基础类方法掷出的违例相同,或者从后者衍生。在这种情况下,C++实际上能够在编译期间检查违例规范。

我们必须认识到这一点:尽管违例规范是由编译器在继承期间强行遵守的,但违例规范并不属于方法类型的一部分,后者仅包括了方法名以及自变量类型。因此,我们不可在违例规范的基础上覆盖方法。除此以外,尽管违例规范存在于一个方法的基础类版本中,但并不表示它必须在方法的衍生类版本中存在。这与方法的“继承”颇有不同(进行继承时,基础类中的方法也必须在衍生类中存在)。换言之,用于一个特定方法的“违例规范接口”可能在继承和覆盖时变得更“窄”,但它不会变得更“宽”——这与继承时的类接口规则是正好相反的。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索storm
, 基础
, 方法
, 构建一个类
, throws
, 一个
基础类
java违例、java限制输入的格式、java list的长度限制、java string 长度限制、java上传文件大小限制,以便于您获取更多的相关知识。

时间: 2024-10-30 16:28:26

java违例的限制的相关文章

标准Java违例

Java包含了一个名为Throwable的类,它对可以作为违例"掷"出的所有东西进行了描述.Throwable对象有两种常规类型(亦即"从Throwable继承").其中,Error代表编译期和系统错误,我们一般不必特意捕获它们(除在特殊情况以外).Exception是可以从任何标准Java库的类方法中"掷"出的基本类型.此外,它们亦可从我们自己的方法以及运行期偶发事件中"掷"出. 为获得违例的一个综合概念,最好的方法是阅读由

JNI和Java违例

利用JNI,可丢弃.捕捉.打印以及重新丢弃Java异常,就象在一个Java程序里那样.但对程序员来说,需自行调用专用的JNI函数,以便对异常进行处理.下面列出用于异常处理的一些JNI函数: ■Throw():丢弃一个现有的异常对象:在固有方法中用于重新丢弃一个异常. ■ThrowNew():生成一个新的异常对象,并将其丢弃. ■ExceptionOccurred():判断一个异常是否已被丢弃,但尚未清除. ■ExceptionDescribe():打印一个异常和堆栈跟踪信息. ■Exceptio

[学习笔记]Thinking in Java (the 2nd edition) Study Note (3)

笔记 第9章 违例差错控制 Java的基本原理就是"形式错误的代码不会运行".<1>在Java中,对那些要调用方法的客户程序员,我们要通知他们可能从自己的方法里"掷"出违例.这是一种有礼貌的做法,只有它才能使客户程序员准确地知道要编写什么代码来捕获所有潜在的违例.当然,若你同时提供了源码,客户程序员甚至能全盘检查代码,找出相应的throw语句.但尽管如此,通常并不随同源码提供库.为解决这个问题,Java提供了一种特殊的语法格式(并强迫我们采用),以便礼貌

用finally清除违例

无论一个违例是否在try块中发生,我们经常都想执行一些特定的代码.对一些特定的操作,经常都会遇到这种情况,但在恢复内存时一般都不需要(因为垃圾收集器会自动照料一切).为达到这个目的,可在所有违例控制器的末尾使用一个finally从句(注释④).所以完整的违例控制小节象下面这个样子: try { // 要保卫的区域: // 可能"掷"出A,B,或C的危险情况 } catch (A a1) { // 控制器 A } catch (B b1) { // 控制器 B } catch (C c1

创建自己的违例

并不一定非要使用Java违例.这一点必须掌握,因为经常都需要创建自己的违例,以便指出自己的库可能生成的一个特殊错误--但创建Java分级结构的时候,这个错误是无法预知的. 为创建自己的违例类,必须从一个现有的违例类型继承--最好在含义上与新违例近似.继承一个违例相当简单:   //: Inheriting.java // Inheriting your own exceptions class MyException extends Exception { public MyException(

RuntimeException的特殊情况

本章的第一个例子是: if(t == null) throw new NullPointerException(); 看起来似乎在传递进入一个方法的每个句柄中都必须检查null(因为不知道调用者是否已传递了一个有效的句柄),这无疑是相当可怕的.但幸运的是,我们根本不必这样做--它属于Java进行的标准运行期检查的一部分.若对一个空句柄发出了调用,Java会自动产生一个NullPointerException违例.所以上述代码在任何情况下都是多余的. 这个类别里含有一系列违例类型.它们全部由Jav

Java的违例控制:解决错误

从最古老的程序设计语言开始,错误控制一直都是设计者们需要解决的一个大问题.由于很难设计出一套完美的错误控制方案,许多语言干脆将问题简单地忽略掉,将其转嫁给库设计人员.对大多数错误控制方案来说,最主要的一个问题是它们严重依赖程序员的警觉性,而不是依赖语言本身的强制标准.如果程序员不够警惕--若比较匆忙,这几乎是肯定会发生的--程序所依赖的错误控制方案便会失效. "违例控制"将错误控制方案内置到程序设计语言中,有时甚至内建到操作系统内.这里的"违例"(Exception

java的违例规范

在Java中,对那些要调用方法的客户程序员,我们要通知他们可能从自己的方法里"掷"出违例.这是一种有礼貌的做法,只有它才能使客户程序员准确地知道要编写什么代码来捕获所有潜在的违例.当然,若你同时提供了源码,客户程序员甚至能全盘检查代码,找出相应的throw语句.但尽管如此,通常并不随同源码提供库.为解决这个问题,Java提供了一种特殊的语法格式(并强迫我们采用),以便礼貌地告诉客户程序员该方法会"掷"出什么违例,令对方方便地加以控制.这便是我们在这里要讲述的&quo

面向 Java 开发人员的 Ajax: Google Web Toolkit 入门

简介: Ajax 被用于创建更加动态和交互性更好的 Web 应用程序.Google Web Toolkit (简称GWT) 是 Google 推出的 Ajax 应用开发包,GWT 支持开发者使用Java 语言开发 Ajax 应用.本文中作者将介绍如何使用 GWT 开发 Ajax 应用的基本方法和步骤. ## Ajax简介 ## Ajax是 Asynchronous JavaScript and XML(以及 DHTML 等)的缩写,由XHTML.CSS.JavaScript.XMLHttpReq