JAVA SE 7中的异常处理

  • 带资源的try语句

使用这种新的语法,在try语句中打开的资源可以自动清理。例如:

在使用完这个输入流后,不用费心关闭。JAVA运行时会自动关闭这个输入流。

可以在try块中包含多个资源,每个用分号隔开。例如:

  •  结合异常处理

如果多个异常处理程序都执行同一段代码,则可以把它们结合在一起。例如:

  •  final Re-throw

以上代码将无法编译,因为我们正试图抛出更通用的异常。为了编译代码,需要在throws 子句中添加Exception类型。如果compute方法重写的方法不声明抛出Exception 类型,这也将不能编译。Java SE 7 解决了这个问题,可以在catch块中添加final 关键字,如下所示:

catch (final Exception e){ ... }

在catch块中使用final关键字,使得能够抛出发生的确切子类异常。例如,如果IOException 发生,那么IOException将被抛出;如果ParseException 发生,那么ParseException将被抛出。final关键字允许抛出发生的确切异常,而不需要添加Exception类型到方法签名中。

 

JAVA中的嵌套类

定义:

一个类的定义可能被嵌入另一个类中,这样的类被称为内部类。内部类可以访问外部类中定义的变量,内部类可以定义在类的方法体中。

局部类在代码块中声明,并且只在代码块中是可见的,就像其他的方法变量一样。

没有名字的局部类被称为匿名类。当仅仅需要类的单个实例是,可以使用匿名类,这也似的代码更具可读性。

使用嵌套类的原因:

  • 它们允许对相关类进行逻辑分组
  • 它们提供增强的封装特性
  • 它们使得代码具有更好的可读性和可维护性

嵌套类的分类:

  • 静态类
  • 非静态类(内部类)
    • 局部类
    • 匿名类

 创建静态嵌套类的对象的语法:

 创建非静态嵌套类(内部类):

内部类与外部类的实例相关联,可以直接访问外部类的字段和方法。内部类不能定义任何静态成员,因为内部类总是与实例相关联。要创建内部类的实例,就必须有外部类的对象。例如:

InnerOddsIterator是内部类,要创建这个类的实例,可以使用this.new调用,其中的this指向当前类的实例。

使用内部类的要点:

  • 内部类的名字必须与包含内部类的外部类的名字不同
  • 在编译外部类是,编译器会为每一个内部类生成单独的.class文件,.class文件的名字为OuterClassName$InnerClassName
  • 内部类可以使用外部类的类和实例变量,以及封闭块的局部变量
  • 内部类可以使用任何可用的访问修饰符进行声明,私有的内部类只能在外部类的范围内访问
  • 内部类可以是接口,然后由另一个内部类实现这个接口
  • 内不聊了可以是抽象的被声明为static的内部类会自动变成TopLevel类
  • 在内部类中不能声明static成员,除非内部类本身被声明为static
  • static关键字可以应用于内部类,但不能应用于外部类

局部类的重要特性:

  • 局部类仅 在定义自身的代码块中是可见的和可用的
  • 处理访问包含类中定义的字段外,局部类还可以访问任何局部变量、方法参数或在局部方法定义的作用域内的异常参数,假设它们都使用final限定符声明
  • 局部类不能使用new和super关键字
  • 局部类不能包含声明为static的字段、方法或类,因为嵌套接口是隐式静态的,局部类可能不包含嵌套接口的定义
  • 局部类不能使用public、protected、private和static修饰符声明,这些修饰符只能用于类的成员,并且不得用于局部类的声明
  • 局部类不能与任何外部类具有相同的名字
  • 接口不能被局部定义
  • 局部类可以使用自身作用域内可见的任何final局部变量或参数。

注意:如果定义在方法体中的内部类的方法师徒访问没有声明为final的方法形参,就会产生编译时错误,必须这样做以确保方法不能修改在形参中指定的变量的值。例:

 使用匿名类的限制:

  • 匿名类不能有构造函数,因为没有与之相关联的名字
  • 匿名类不能定义静态字段、方法或类
  • 在匿名类中不能定义嵌套接口,因为这些接口是隐式静态的
  • 不能匿名地定义接口
  • 像局部类一样,匿名内部类不可以声明为public、private、protected或static。事实上,在匿名类的定义语法中,并没有在声明中指定任何修饰符的规定。

使用匿名类的准则:

通常情况下,在下列上下文中应该考虑使用匿名类而不是局部类:

  • 类的主体很短
  • 只需要一个类的实例
  • 类在定义后立刻被使用
  • 类的名称不会是代码更容易理解

摘自《Java 7 编程高级进阶》 Poornachandra Sarang 著 曹如进 张方勇 译 清华大学出版社

JAVA中的final关键字

final关键字可应用于类、方法或变量。

注意点:

  • final修饰的类不能被子类化(扩展)
  • final修饰的方法不能被重写
  • 空缺final变量必须在构造函数中初始化。如果空缺final变量在某个构造函数中初始化,就必须在类的所有重载构造函数中进行初始化
  • 空缺final变量仅可以设置一次
  • 空缺final变量必须在使用前进行设置
  • 由于private 和 static 方法不能在子类中被重写,因此它们总是隐式地为final

注释:空缺final变量是一种声明为final但未初始化的变量,如 public final int ID;

好处:

  1. 可以显示防止子类中的方法重写。
  2. final方法会告诉编译器对于final方法的调用不需要动态绑定,这会让代码便得略微更有效些。静态绑定总是比动态绑定高兴,因为在动态绑定中,运行时需要解析方法调用。
  3. 能带来更好的效率。将方法标记为final可以让编译器将所有的final方法的调用转变为内联调用。当编译器看到final方法调用时,可以根据自己的判断,略去一般通过方法调用机制插入代码的那套路数。调用机制包括将方法参数压栈、清除栈参数和最后处理返回值。与这套方法不同,编译器现在可以在方法体中使用实际代码替换方法调用。不过,如果方法过大,那么在方法调用和返回方面实际节省的好处将会变得很小,这取决于方法内部花去的时间总量。一般来说,短小的方法能够从内联获益。内联的好处不局限与方法的大小,因为这还常常会带来一些进一步的优化,如减少无用代码和更多内联。

注意:Java不允许显示第标记方法为内联方法。编译器会根据自己的判断,在代码中奖方法标记为“final”。

摘自《Java 7 编程高级进阶》 Poornachandra Sarang 著 曹如进 张方勇 译 清华大学出版社

JAVA中的继承注意点

  • 子类的构造函数中,若显示使用super调用父类的构造函数,或使用this调用本类中的其他构造函数时,此调用语句必须是构造函数中的第一句,否则报错。
  • 子类的构造函数中,若没有显示地使用super调用父类的构造函数,则默认调用父类的无参构造函数,若父类中没有此无参构造函数且编译器不提供此无参构造函数,则报错。

 

代码描述:

针对第一条的代码:

 

执行命令:

 

针对第二条的代码:

 

 

 

执行命令: