调用常量时,不执行静态代码块

1.编译期常量和运行时常量:

1.1.编译期常量 public static final int A1=2;//编译期就确定A1对应的数值,并把A1的相关引用都会直接替换成其对应的数值2

1.2.运行期常量 public static final int A1="hello".length();//在运行时才能确定具体数值

public class Test {


    public static void main(String[] args) {
        System.out.println(A.A1);
      //A1变量可以被调用是因为  A1=2;  在编译期 确定并存储到内存的(内存中有A1)

    }
}


class A{
    public static final  int A1=2;//编译期常量: 编译期 确定并存储到内存的

    //public static  int A1=2;//静态变量

    static {//对A实例化的时候//不执行是因为没有new A
        System.out.println("static block");
    }
}

遇到new、getstatic或invokestatic这几条字节码指令时,如果类没有初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:

(1)使用new关键字实例化对象时

(2)读取或设置一个类的静态字段(被final修饰、已在编译期把结果放入常量池的静态字段除外)时//调用静态变量时

(3)调用一个类的静态方法时

以上内容摘抄自《深入理解Java虚拟机》7.2节 类加载的时机

2.根据程序运行结果,我们就可以得出结论了:编译期常量不依赖类,不会引起类的初始化;而运行时常量依赖类,会引起类的初始化。

3 编译时常量使用的风险
由于编译时,常量会被替换为字面量,这是JVM提高运行效率优化代码的一种方式,但有时候也会带来一定的麻烦。

如果我们项目超大,项目整个编译一次特别耗费时间,那么我们有可能会只编译代码修改的部分。而一旦我们修改了常量A,但又未重新编译所有引用A常量的部分(即.java文件),那么就会导致未重新编译的那部分代码继续使用A的旧值。

下面写个非常简单的实验看看。

定义常量的Book类:

public class Book {
    //编译期常量,书本价格10元
	public static final int price = 10;
}

定义Student类和mian方法:

public class Student {
	
	public int cost = Book.price;
    
	public void printCost() {
		System.out.println("书费"+this.cost+"元");
	}
	
	public static void main(String[] args) {
		Student stu = new Student();
		stu.printCost();
	}
}
/* 打印输出:
 * 书费10元
 */

现在修改Book.java文件中的price=5,并使用javac命令仅仅只重新编译Book.java文件:

javac Book.java

执行java命令,再次运行main方法:

java Student

观察结果:结果与第一次相同,书费10元

第二次运行结果
 

————————————————
版权声明:本文为CSDN博主「Rhine404」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34802416/article/details/83548369

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,静态属性、静态方法和静态代码块是与类相关联而不是与类的实例相关联的。以下是对它们的详细解释: 静态属性是与类相关联的属性,它在整个程序运行期间只有一份副本,并且在类加载被初始化。我们可以通过类名直接访问静态属性,而不需要实例化类。静态属性通常用于存储与类相关的常量或共享的数据,例如记录类创建实例个数的计数器。 静态方法是只能调用静态属性和其他静态方法的方法。它们被声明为静态以便我们可以在不创建类的实例的情况下直接调用它们。在静态方法内部,我们不能直接访问非静态属性和方法,因为它们需要实例化才能被访问。静态方法通常用于执行与类相关的辅助功能,例如数学计算、操作静态属性等。 静态代码块是在类加载执行代码块。它用于初始化静态属性或执行一些只需要在类加载执行一次的操作。静态代码块在类加载自动执行,不需要显式调用。在静态代码块内部,我们可以执行任何合法的操作,例如对静态属性的初始化、加载资源文件等。 总的来说,静态属性、静态方法和静态代码块都与类相关联,而不是与类的实例相关联。它们不需要创建类的实例就可以使用,可以通过类名直接访问。静态属性存储与类相关的常量或共享的数据,静态方法执行与类相关的辅助功能,静态代码块执行只需要在类加载执行一次的操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值