源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

小议Java中final关键字使用时的注意点

  • 时间:2021-08-21 00:31 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:小议Java中final关键字使用时的注意点
[b]final 类 [/b]final 类不能被继承,同时,一旦用 final 修饰了类,也就意味着 final 类中的所有方法都被隐式地指定为 final 方法 [b]final 方法 [/b]在类继承的过程中,对于父类中的 final 方法,子类不能修改和覆盖。 private 方法都被隐式指定为 final 方法。 有两个原因使用 final 方法: [list] [*]锁定方法,防止被子类修改其含义[/*] [*]在早期的 java 实现版本中,final 方法被实现为内嵌调用,可以提升性能[/*] [/list] [b]final 变量 [/b]final 关键字用来修饰变量是最常用的用法,如果修饰成员变量,则必须在定义时或者构造方法中初始化,且一经初始化此后不能再进行任何赋值。 针对基本类型和类对象有着不同的含义: [list] [*]对于基本类型,final 变量一经初始化,此后不能再改变该变量的值[/*] [*]对于类对象,已经初始化后,不能让这个变量再指向另一个对象,但他指向的对象的内容是可以改变的[/*] [/list] static final 域称为编译期常量,一般全部大写。 示例
class Glyph {
 void draw() {
  System.out.println("Glyph.draw()");
 }
 Glyph() {
  System.out.println("Glyph() before draw()");
  draw();
  System.out.println("Glyph() after draw()");
 }
}
class RoundGlyph extends Glyph {
 private int redius = 1;
 RoundGlyph(int r) {
  radius = r;
  System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
 }
 void draw() {
  System.out.println("RoundGlyph.draw(), radius = " + radius);
 }
}
public class RolyConstructors {
 public static void main(String[] args) {
  new RoundGlyph(5);
 }
}
输出结果:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
上面的代码展示了类初始化过程以及隐藏的灾难性问题。 main 函数中以参数 5 调用 RoundGlyph 的构造函数创建了 RoundGlyph 对象,在 RoundGlyph 构造方法执行前调用了其父类 Glyph 的构造方法。 然而,在父类 Glyph 的构造方法中调用了 draw 方法,由于多态性,此时实际上调用了子类的 draw 方法,然而子类的 redius 此时还没有通过构造器初始化,因此输出了:
RoundGlyph.draw(), radius = 0
这显然不是我们想要的结果,因此需要注意: [list] [*]用尽可能简单的方法初始化类成员[/*] [*]在构造器中最好只调用 final 方法[/*] [/list] 第二条的原因是 final 不会应用多态性,因此可以保证调用的是当前对象的相应方法,而不是初始化工作还没有进行的子类的覆盖方法。 [b]总结final的内存分配方式: 1.修饰变量: [/b]通常情况下,final变量有3个地方可以赋值:直接赋值,构造函数中,或是初始化块中。 (1)初始化: 由于在java的语法中,声明和初始化是联系在一起的, 也就是说:如果你不显示的初始化一个变量,系统会自动用一个默认值来对其进行初始化。(如int就是0) 对于final变量,在声明时,如果你没有赋值,系统默认这是一个空白域,在构造函数进行初始化, 如果是静态的,则可以在初始化块。 (2)内存: 常量(final变量)和非final变量的处理方式是不一样的。 每一个类型在用到一个常量时,都会复制一份到自己的常量池中。 常量也像类变量(static)一样保存在方法区,只不过他保存在常量池。 (可能是,类变量被所有实例共享,而常量池是每个实例独有的。) [b]2.修饰方法: [/b]保存在方法区,并且可以被函数代码直接替换,而不用等到执行时再决定具体是那个函数。 [b]3.修饰类: [/b]保存在方法区。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部