Java中静态常量和静态变量的区别 您所在的位置:网站首页 JAVA的变量都是静态的 Java中静态常量和静态变量的区别

Java中静态常量和静态变量的区别

2024-02-14 11:24| 来源: 网络整理| 查看: 265

在jvm参数当中一共有以下三种

-XX:+ 加号表示开启选项-XX:- 减号表示关闭选项-XX:=:表示将option的值设置为value在idea中添加vm option参数,–XX:+TraceClassLoading用于打印类加载信息

如下:

测试java中静态常量和静态变量区别的样例,表明两者加载时的区别。

StaticClass类中定义了静态常量FIANL_VALUE和静态变量VALUE,静态代码块的打印语句表示类被加载:

public class StaticClass {       static {           System.out.println("StaticClass loading...");       }              public static String VALUE = "static value loading";              public static final String FIANL_VALUE = "fianl value loading";   }  

StaticClassLoadTest类用于测试静态变量的加载:

public class StaticClassLoadTest { public static void main(String[] args) { System.out.println("StaticClassLoadTest..."); printStatic(); //printnewStatic(); } private static void printStatic() { System.out.println(StaticClass.FIANL_VALUE); System.out.println(StaticClass.VALUE); } private static void printnewStatic() { System.out.println(StaticClass.FINAL_VALUE_STR); System.out.println(StaticClass.VALUE); } } 输出:

[Loaded java.net.InetAddress$Cache$Type from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.InetAddressImplFactory from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar][Loaded com.xxx.domain.StaticClassLoadTest from file:/D:/work/fix/xxx.ui/target/classes/] [Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.InetAddressImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.Inet6AddressImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded sun.net.spi.nameservice.NameService from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.InetAddress$2 from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] StaticClassLoadTest...fianl value loading [Loaded sun.net.util.IPAddressUtil from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.Inet4Address from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.SocksConsts from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar][Loaded com.xxx.domain.StaticClass from file:/D:/work/fix/xxx.ui/target/classes/] [Loaded java.net.SocketOptions from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar]StaticClass loading... [Loaded java.net.SocketImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar]static value loading

输出显示在打印静态常量时,StaticClass类没有被加载,在输出静态变量的前才打印类加载信息。这表明类的未加载的情况下也能引用其静态常量信息,原因是因为常量值存储在JVM内存中的常量区中,在类不加载时即可访问。

注:经过编译优化,静态常量 FIANL_VALUE 已经存到NotInit类自身常量池中,不会加载StaticClass  

但是不能说所有的静态常用访问都不需要类的加载,这里还要判断这个常量是否属于“编译期常量”,即在编译期即可确定常量值。如果常量值必须在运行时才能确定,如常量值是一个随机值,也会引起类的加载,如下:

public static final StringBuilder FINAL_VALUE_STR = new StringBuilder("new fianl value loading");

输出: 

[Loaded com.xxx.domain.StaticClassLoadTest from file:/D:/work/fix/xxx.ui/target/classes/] [Loaded sun.net.util.IPAddressUtil from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.Inet4Address from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded sun.launcher.LauncherHelper$FXHelper from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.lang.Class$MethodArray from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.SocksConsts from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] StaticClassLoadTest... [Loaded java.net.SocketOptions from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.SocketImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.AbstractPlainSocketImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.PlainSocketImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.SocksSocketImpl from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar] [Loaded java.net.AbstractPlainSocketImpl$1 from C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar][Loaded com.xxx.domain.StaticClass from file:/D:/work/fix/xxx.ui/target/classes/]StaticClass loading... new fianl value loading static value loading

总结:

final修饰的实例属性,在实例创建的时候才会赋值。

static修饰的类属性,在类加载的准备阶段赋初值,初始化阶段赋值。

static+final修饰的String类型或者基本类型常量,JVM规范是在初始化阶段赋值,但是HotSpot VM直接在准备阶段就赋值了。

static+final修饰的其他引用类型常量,赋值步骤和第二点的流程是一样的。

参考:你知道Java中final和static修饰的变量是在什么时候赋值的吗?_CoderW喜欢写博客的博客-CSDN博客  



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有