关于JAVA final关键字修饰类变量时,类变量初始化的问题
class Price {
//类成员INSTANCE是Price实例
static Price INSTANCE = new Price(2.8);
//默认价格initPrice
static double initPrice = 20;
//当前价格
double currentPrice;
//构造函数
public Price(double discount){
System.out.println("执行了构造函数 initPrice:"+ initPrice);
currentPrice = initPrice - discount;
}
}
public class PriceTest {
public static void main(String[] args) {
System.out.println(Price.INSTANCE.currentPrice);
Price p = new Price(2.8);
System.out.println(p.currentPrice);
}
}
执行如果如下:
执行了构造函数 initPrice:0.0
-2.8
执行了构造函数 initPrice:20.0
17.2
当我在Price类中把initPrice用final修饰,即定义为:final static double initPrice = 20; 其它不变,执行的结果如下:
执行了构造函数 initPrice:20.0
17.2
执行了构造函数 initPrice:20.0
17.2
我想问一下,当类变量被final修饰时,类变量的初始化工作是怎样的呢?没分了求好心人帮忙解答。 展开
程序运行时机优先级是:类加载-->静态代码块运行-->静态变量初始化-->对应的构造函数运行--->
System.out.println(Price.INSTANCE.currentPrice):
Price.INSTANCE:调用了构造方法,即打印"执行了构造函数 initPrice:"+ initPrice,此时initPrice虽然也是静态的,但还没有被执行到,所以此时的值为0。如果把“static double initPrice = 20;”放在“static Price INSTANCE = new Price(2.8);”前面结果就不一样了。
currentPrice = initPrice - discount;:
Price.INSTANCE:static Price INSTANCE = new Price(2.8);创建了Price对象,传入的参数是2.8,所以currentPrice = 0 - 2.8,结果为 -2.8。
Price p = new Price(2.8);:
静态成员是在构造方法之前就完成了初始化操作,所以可以用类名直接调用,没有被静态化的成员是不能被类名直接调用的,必须创建对象进行初始化操作。而这里new创建了Price对象,就完成了Price里面所有成员的初始化操作,各个成员就都有了初始值。创建对象的时候会调用构造法,这里构造方法就是public Price(double discount){},所以就执行了构造方法里面的currentPrice = initPrice - discount,即currentPrice=20-2.8=17.2。
至于static double initPrice = 20被final修饰了,final是在类加载的时候就被赋值了,运行时机优先级更高吧,并且final赋值后就不能被修改。所以结果为:
执行了构造函数 initPrice:20.0
17.2
执行了构造函数 initPrice:20.0
17.2
这段是疯狂java里面的吧。
初始化一个类分两步:
初始化内存空间,第一次初始化类的时候先分配内存空间,此刻INSTANCE为null,initPrice是0,currentPrice为0.0。
初始化代码,按顺序执行,先初始化INSTANCE实例,得到的值就是currentPrice为-2.8
关于final修饰的变量,在系统中为宏变量,在编译的时候就已经分配好内存和值,是系统常量,在其他使用的地方都是直接替换的。反编译代码可以看到所有的final变量都变成了常数。所以不论你什么时候初始化类,都是直接替换相减