`
talentluke
  • 浏览: 593219 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

类静态变量初始化

 
阅读更多

class A
{
        public static final A a=null;//改为int a = 1;//下面的静态块就不执行
        static{System.out.println("A000000000");}
}
public class Test
{
        public static void main(String[] args) 
        {
                Object o=A.a;
        } 

通过javap -c Test查看经过编译后的字节码就明白了

 

 不单单是null的问题,但null确实是问题之一

更重要的一个问题是会写到A.class常量池中的类型是有限的:String和几个基本类型

而A.a的类型是A

如果将a的类型改为String,为null仍然会去getstatic

如果a的类型为String,且有一个字符串值,那么A就使用ldc指令直接从B的常量池中取值,这表示a的值在编译的时候已经放到A.class中了。

假如A.a的值是编译期常量,如果Test类中使用了A.a,编译的是时候在Test.class存的就不是A.a的符号引用,而直接是A.a的值,这就不是主动使用了。

 

当然,这也并不是说所有String和几个基本类型的常量就会放到B的常量池中去

比如a是int类型,其值为32767,使用的就是sipush  32767,表示操作数直接跟在操作码后面

如果值为32768,还是会从常量池用ldc指令取值

但,不管如何,这种值都放到了Test.class中,要么在Test的常量池中,要么跟在字节码后面作为参数

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics