最近在补《thinking in java》...有一节提到了加载类需要做的一些准备...我照着书本敲了一下代码...同时稍微修改了一下书本上的代码....

 package charpter14;

 import java.util.Random;

 class Initable{
static{
System.out.println("haha");
}
static final int staticFinal = 47;
static final int staticFinal2 = ClassInitialization.rand.nextInt(1000);
static{
System.out.println("Initialing Initable");
}
} class Initable2{
static int staticNonFinal = 147;
static{
System.out.println("Initialing Initable2");
a = 1;
}
static int a = 7;
} class Initable3{
static int staticNonFinal = 74;
static{
System.out.println("Initialing Initable3");
}
} public class ClassInitialization {
public static Random rand = new Random(47);
public static void main(String[] args) throws Exception {
Class initable = Initable.class;
System.out.println("After creating Initable ref");
System.out.println(Initable.staticFinal);
System.out.println(Initable.staticFinal2);
System.out.println(Initable2.staticNonFinal);
Class initable3 = Class.forName("charpter14.Initable3");
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNonFinal);
System.out.println(Initable2.a);
}
}

输出结果:

After creating Initable ref
47
haha
Initialing Initable
258
Initialing Initable2
147
Initialing Initable3
After creating Initable3 ref
74
7


分析

  1. Class initable = Initable.class;的时候什么都没有输出,说明了调用.class的时候并不会初始化Initable类.
  2. 47 haha Initialing Initable 258; 调用Initable.staticFinal的时候因为staticFinal变量是static final 并且是 基本数据类型字面值,不是通过方法得到的值的时候也不会初始化这个类. 调用staticFinal2的时候,因为调用了其他类的方法,所以要先初始化Initable这个类,所以会去做static区块的内容.因此会输出haha 和 Initialing Initable,然后初始化完毕,再输出258.

  3. 调用Initable2.staticNonFinal的时候,因为这个变量不是final类型的,所以要先初始化类,所以去做static区块,因此输出Initialing Initable2以后再输出47.

问题

最后我想一个问题,这点有点奇怪....我有点想不明白...输出Initable2.a的值是7不是1.说明了Initable2的static区块中的a=1是先于赋值static int a = 7执行的...这里有个问题就是..既然如此的话那执行a=1的时候a变量的类型都是不确定的为什么能赋值呢...我想可能是因为static int a = 7的时候..第一步做的是static int a=0,就是先分配空间,没有赋值; 然后执行static区块,赋值a = 1,这样a的类型就确定了,能赋值.然后再执行a = 7.如果确实是这样的话..那还是有一个问题.....(Σ( ° △ °|||)︴问题好多啊).....

public class Test {
static{
a = 99;
System.out.println(a);
}
static int a = 11; }

如果刚才的推论是正确的话这里应该会输出99....因为先给a分配空间,再赋值a=99;再输出a,就是99...然后再赋值a=11.....

可是实际上eclipse会提示你这里有编译错误..

eclipse会告诉你Cannot reference a field before it is defined.

它会告诉你a是没有定义的,所以你这里不能输出a....

这点我一直想不明白...

最新文章

  1. CSS+Javascript
  2. iOS中block的使用、实现底层、循环引用、存储位置
  3. 虚拟机VMware怎么完全卸载干净
  4. 【CodeForces 672B】Different is Good
  5. 初始BOM
  6. salt 批量部署与配置
  7. Cisco 交换机与路由器故障处理方法分享
  8. python关键字
  9. kendo ui中grid页面参数问题
  10. Live555 实战之框架简单介绍
  11. 终结python协程----从yield到actor模型的实现
  12. Typora程序员的记事本.Typora常用快捷操作
  13. 【DOS】Win7系统文件夹名太长无法删除问题的解决
  14. python基础5 while循环
  15. hiredis 使用 linux c++
  16. poj 2251 Dungeon Master (BFS 三维)
  17. 虚拟机怎么发送ctrl+alt+delete组合键
  18. angularjs学习第三天笔记(过滤器第二篇---filter过滤器及其自定义过滤器)
  19. SVM学习(五):松弛变量与惩罚因子
  20. glassfish任意文件读取漏洞解析

热门文章

  1. 推荐一些python Beautiful Soup学习网址
  2. monkeyrunner之电脑安装驱动(五)
  3. python爬虫学习(1) —— 从urllib说起
  4. 配置jpa
  5. 第12章 Java字符串
  6. 操作系统IO模型
  7. ThinkPHP常用配置路径
  8. ajax实现下拉菜单无刷新加载更多
  9. Apache Shiro系列四,概述 —— Shiro的架构
  10. bzoj1800[Ahoi2009]fly 飞行棋 暴力枚举