Posts

Showing posts with the label 修饰符

final关键字

  final的含义为“不可改变的”,不想做改变通常有两种理由:设计或效率,下面谈论了可能使用到final的三种情况:域,方法和类 final域 将数据声明为final是因为需要一个: 一个永不改变的编译时常量 一个在运行时被初始化的值,而你不希望它被改变 在这里附上运行时/编译时的定义,了解可以跳过:  Java的引用变量有两个类型,一个是编译时类型,一个是运行时类型,编译时类型由声明该变量时使用   的类型决定,运行时类型由实际赋给该变量的对象决定。   Person p=new Women()(Women类继承自Person类)那么,假如p的属性修饰符为public 那么访问属性时得到 的是Person类的属性还是Women类的属性?方法调用又是哪个类?   答案:会得到Person类的属性,调用  Women类的方法。为什么会这样呢?这里就需要知道什么是编译时类型和运行时类型,Java程序状态会分为编译和运行这两种状态,编译时,JVM会在栈中静态创建基本数据变量,和引用数据变量的引用。回到刚刚那句代码,显然,p这个引用就是在编译时创建的。那么,p的编译时类型就是Person了,当运行这句java代码时,JVM在堆中为p新建一块内存,对应new Women()这句代码,所以p的运行时类型就是Women 编译时常量存在什么样的风险?   编译时常量,在使用时会被直接写成值,而不会再从原来的类中读取。这样就会导致问题的产生:如果   A类定义了常量,B类使用了常量,并且都进行了编译。当A类的源码被改动了,常量的值发生了变化。我们对A类进行了重新编译,但是没有对B类进行重新编译;那么B类中用到的是原来A类中的常量值,即旧值。这就导致了风险的发生。  对于编译时常量(static final修饰,根据惯例编译时常量用大写表示,并使用下划线分隔各个单词)这种情况,编译器可以将常量带入任何可能用到它的计算式中,在编译时执行计算式,这减轻了一些运行时负担。在Java中,这类常量必须是基本数据类型,再对其定义的同时必须进行赋值。编译时常量只占据一个一段不能改变的储存空间。 而对 ...