牛刀小试1.

  试一把静态代码块、实例化代码块和构造函数的执行顺序

public class People
{
public static int num = 0;//静态变量初始化
String name;//初始化为null //构造函数
public People(String name) {
System.out.println(num + ":构造函数初始化");
this.name = name; //将name引用指向传入参数
num++; //构造函数执行结束num值+1
} //实例初始化块
{
System.out.println(num + ":实例初始化块");
} //静态初始化块
static {
System.out.println(num + ":静态初始化块");
} public static void main(String[] args) {
People people1 = new People("xunzhaorendaxia");
People people2 = new People("xunzhaorendaxia");
}
}

输出结果:

0:静态初始化块
0:实例初始化块
0:构造函数初始化
1:实例初始化块
1:构造函数初始化

  反编译后的代码:

public class People
{
public static int num = 0;
String name; public People(String name)
{
System.out.println(num + ":实例初始化块"); System.out.println(num + ":构造函数初始化");
this.name = name;
num += 1;
} public static void main(String[] args)
{
People people1 = new People("xunzhoarendaxia");
People people2 = new People("xunzhaorendaxia");
} static
{
System.out.println(num + ":静态初始化块");
}
}

结论:

1)执行先后顺序,静态初始化块>实例初始化块>构造函数初始化。
2)静态初始化块只在类加载时执行一次,实例初始化块和构造函数初始化每次实例化类时都执行。
3)实例初始化块的代码,其实被放进了构造函数里面,且放在构造函数内容的前面。

牛刀小试2.

  测试一种初始化HashMap的方式(使用场景是想优雅的初始化一些Key-Value的参数):

public class Person
{
public static int num = 0;//静态变量初始化
String name;//初始化为null //构造函数
public Person(String name) {
System.out.println(num + ":构造函数初始化");
this.name = name; //将name引用指向传入参数
num++; //构造函数执行结束num值+1
} //实例初始化块
{
System.out.println(num + ":实例初始化块");
}
static Map map1=null;
//静态初始化块
static {
System.out.println(num + ":静态初始化块"); map1 = new HashMap<String,String>(){
{
put("1", "111");
put("2", "2222");
}
};
} public final static Map map = new HashMap(); public static void main(String[] args) {
Person people1 = new Person("xunzhaorendaxia");
Person people2 = new Person("xunzhaorendaxia"); System.out.println(map1.toString());
}
}

输出内容:

0:静态初始化块
0:实例初始化块
0:构造函数初始化
1:实例初始化块
1:构造函数初始化
{1=111, 2=2222}

反编译文件中会出现两个class文件:

下面是反编译的代码:

public class Person {
public static int num = 0;
String name;
static Map map1 = null;
public static final Map map; static {
System.out.println(num + ":静态初始化块");
map1 = new 1();//这里new 1()肯定是编译优化的,怎么简单省空间怎么来。
map = new HashMap();
} public Person(String name) {
System.out.println(num + ":实例初始化块");
System.out.println(num + ":构造函数初始化");
this.name = name;
++num;
} public static void main(String[] args) {
new Person("xunzhaorendaxia");
new Person("xunzhaorendaxia");
System.out.println(map1.toString());
}
}
class Person$1 extends HashMap<String, String> {
Person$1() {
this.put("1", "111");
this.put("2", "2222");
}
}

  

下面提出个人的解析观点:

1.Person$1的class文件怎么回事?

答:Person$1.class是内部类的编译文件,即Person类中名为“1”的匿名内部类的编译文件。“1”应该是编译器优化了这里的匿名内部类。(注意查看第二个反编译文件)

2.为啥会出现匿名内部类?好像没有定义啊

答:请注意这里的Person类中HashMap的初始化方式,后面加了{{}}两层大括号,这里第一个外层{}编译器默认是编译成一个继承HashMap的匿名内部类。第二个内层{}本质上是属于实例代码块,即在执行构造方法是最先执行。(不明白的可以参考牛刀小试1)。还有一点需要注意这里的静态代码块初始化HashMap的声明要放在外面,写在静态代码块中会读不到(作用域不够)。

  static Map map1=null;
//静态初始化块
static {
System.out.println(num + ":静态初始化块"); map1 = new HashMap<String,String>(){
{
put("1", "111");
put("2", "2222");
}
};
}

参考链接:https://www.cnblogs.com/xdouby/p/5890083.html

     https://blog.csdn.net/kingzone_2008/article/details/45015301

最新文章

  1. iOS开发-删除字典中的null
  2. (转)Ubuntu samba配置服务文件包
  3. 理解C#值类型和引用类型
  4. 【python】python的列表表达式或解析式,帅就一个字
  5. linunx 定位最耗资源的进程
  6. HDU 1557 权利指数 国家压缩 暴力
  7. 利用JS做到隐藏div和显示div
  8. Highcharts tooltip显示多条线的信息
  9. 带着新人看java虚拟机02
  10. python之路day02--格式化输出、初始编码、运算符
  11. 修复ogg source端意外宕机造成的数据不同步
  12. ESP8266基础篇
  13. luogu4268 Directory Traversal (dfs)
  14. Android:Unable to find explicit activity class
  15. Eclipse和Tomcat使用过程的一些配置、错误等的总结记录
  16. AtCoder Grand Contest 027 C ABland Yard
  17. &lt;记录&gt; PHP Redis操作类
  18. dj 用户认证组件
  19. HDU1069(KB12-C)
  20. js浮点数保留一位小数

热门文章

  1. jsonkit 分解nsarray 时刻 一个错误
  2. Gram 矩阵性质及应用
  3. Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听
  4. 像职业选手样编码:地道Python
  5. python 教程 第十四章、 地址薄作业
  6. Sync Framework Toolkit 开源库
  7. Goutte 获取http response
  8. WPF 4 开发Windows 7 任务栏(Overlay Icon、Thumbnail Toolbar、Progress Bar)
  9. C# HttpWebResponse下载限速
  10. QLocalServer与QLocalSocket进程通讯