JVM对final的支持

来源:互联网 发布:java 启动定时器 编辑:程序博客网 时间:2024/06/17 20:26
         java中的final语义:1. 用于类表示该类是不可继承的;2. 用于属性,表示该类是不可变,这里的不可变,是指,对于基本类型来说值不可变,对于引用来说,引用不可变,但是引用所指向的对象是可变的;3. 用于方法,表示该方法不允许重写。
         在JVM中,ClassFIle文件结构中,有一个access_flag标志位,其中有一个标记位为ACC_FINAL,取值为0X0010,表明该类不允许有子类,也就是final对于类的语义了。每一个类都有一个父类索引super_class,除了Object以外,取值都不为0,也就是含有一个指向constant_pool的有效索引值。JVM会检查super_class指向的父类,若是父类同时设置了ACC_FINAL,则会出错。实际上,这个部分在编译的时候就会进行检查。因为final的类不允许继承,也就是隐含了该类的所有方法都不允许覆盖。从这个角度来说,抽象类和接口,显然是不能声明为final的。
         在方法里面,也有ACC_FINAL标记,该标记和ACC_ABSTRACT是冲突的,也就是说一个方法只能设置为final或者abstract的一种,理由显而易见,若是一个方法同时标记为final和abstract,那么该如何实现这个方法?。ACC_FINAL设置之后,则不会允许子类覆盖该方法,这个检查是在编译器进行的。但是,父类中的private由于对子类是透明的,因此子类也是无法覆盖该方法。有些参考书上说private隐含是final的,我猜测是表现是一样的,但是虚拟机规范里面没有强制要求设置ACC_PRIVATE的方法一定要设置为             ACC_FINAL(接口中的方法强制设置ACC_PUBLIC和ACC_ABSTRACT,从这个角度来说,接口和抽象类的差别就更加小了)。
         在属性当中,也有ACC_FINAL标记位。设置了该标记位之后,就不能设置为ACC_VOLATILE。当设置了ACC_VOLATILE之后,虚拟机将保证所有的线程看到一致的值(虚拟机如何做到这一点有待考证,单单是如何判断值是“一致”的就挺困难的)。

0 0