`

Java-Final

    博客分类:
  • JDK
阅读更多
今天有人问我,Java的对象或者类型修改用Final.
Java中的final关键字通常的指的是“这是无法改变的”。它可能被做为三种的修饰词.------数据,方法,类。
一 final数据
1.在修饰基本类型时,表示它是一个常量,在定义时必须给予赋值.
   特别的一个既是static又是final 的字段只占据一段不能改变的存储空间。
2.在修饰对象或者数组时,它表示对对象或数组的引用恒定不变,然而对象本身却是可以修改的.
  空白final:声明为final但末给定初值的字段,但必须确保空白final在使用前被初始化,一般在构造方法完成。
  final参数:在方法的参数列表以声明的方式将参数指明为final,这意味着在方法里无法修改参数的引用所指向的对象。
二 final方法
1. 把方法锁定,使得在子类(导出类)中不能修改它的含义。
2.效率,一个final方法被调用时会转为内嵌调用,不会使用常规的压栈方式,使得运行效率较高,尤其是在方法体较简单的情况下,
   但也并不绝对。(与C++中的inline关键字类似)
特别的:类中的所有private方法都隐式地指定为是final,所以在继承关系中不存在覆盖问题。
三 final类
声明为final的类不能派生出了子类,也就是不能被继承,一个final类中的所有方法都隐式地指定为final.

可能有人会问了,你说不能改变,你说只占据一段存储空间,你懂JVM的编译规则吗?
首先举下Final数据的例子.
public class MyClass {
        private static final int aa=1;
        int b=3;
        
        public int add(int a,int b){
                return a+b;
        }
} 

Javac MyClass
public class com.tag2.jvm.MyClass {
  
  // Field descriptor #6 I
  private static final int aa = 1;
  
  // Field descriptor #6 I
  int b;
  
  // Method descriptor #11 ()V
  // Stack: 2, Locals: 1
  public MyClass();
     0  aload_0 [this]                                                                    //0:变量到操作数栈
     1  invokespecial java.lang.Object() [13]                               //1:调用需要特殊处理的实例方法:invokespecial
     4  aload_0 [this]                                                                    //4:变量到操作数栈
     5  iconst_3                                                                             //5:常数到操作数栈
     6  putfield com.tag2.jvm.MyClass.b : int [15]                       //6:访问类的域和类实例域,com.tag2.jvm.MyClass.a : int [15]  
     9  return
      Line numbers:
        [pc: 0, line: 3]
        [pc: 4, line: 5]
        [pc: 9, line: 3]
      Local variable table:
        [pc: 0, pc: 10] local: this index: 0 type: com.tag2.jvm.MyClass
    ...
}

大家看以上的编程Class文件,通过JVM指令解析,一般操作步骤是,先声名变量 int aa,int b.然后再把常数也压到栈中,最后赋值的过程。
大家看到final修改的变量不需要赋值[一个既是static又是final 的字段只占据一段不能改变的存储空间]
(声名为静态的是类变量,其访问速度会快(少了一个赋值过程),也就是固定的内存地址,用final修改就是不可改变的存储空间)
用final修改意为不可改为,这意味着在方法里无法修改参数的引用所指向的对象。[引用恒定不变 ,对象本身可以修改]
我上节介绍了设计模式之单例模式,其中Spring用到了两个synchronized (this.startupShutdownMonitor) synchronized (this.singletonObjects)
其中两个对象都是final类型的[Spring的锁对象一般都是Final的,不可改变的,也就保证了其原子性]。



分享到:

相关推荐

Global site tag (gtag.js) - Google Analytics