关于JAVA final关键字修饰类变量时,类变量初始化的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于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

参考技术A

这段是疯狂java里面的吧。

初始化一个类分两步:

    初始化内存空间,第一次初始化类的时候先分配内存空间,此刻INSTANCE为null,initPrice是0,currentPrice为0.0。

    初始化代码,按顺序执行,先初始化INSTANCE实例,得到的值就是currentPrice为-2.8


关于final修饰的变量,在系统中为宏变量,在编译的时候就已经分配好内存和值,是系统常量,在其他使用的地方都是直接替换的。反编译代码可以看到所有的final变量都变成了常数。所以不论你什么时候初始化类,都是直接替换相减

本回答被提问者采纳
参考技术B 使用final修饰的变量在对象生成前就定义好了.....

Java中的final关键字(修饰类修饰方法修饰变量)

在Java面向对象编程中,final关键字大家应该都知道,在匿名内部类使用时可能经常用到。Java中的String类就用了final关键字。final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量),下面看一下final关键字的用法。

原文地址:https://www.cjavapy.com/article/23/

以上是关于关于JAVA final关键字修饰类变量时,类变量初始化的问题的主要内容,如果未能解决你的问题,请参考以下文章

Java中的final关键字(修饰类修饰方法修饰变量)

Java中的final关键字(修饰类修饰方法修饰变量)

Java之final关键字

Java 抽象类

聊聊java中final那点事

聊聊java中final那点事