牛刀小试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

java代码块牛刀小试的更多相关文章

  1. Java代码块详解

    Java中代码块指的是用 {} 包围的代码集合,分为4种:普通代码块,静态代码块,同步代码块,构造代码块 普通代码块: 定义:在方法.循环.判断等语句中出现的代码块 修饰:只能用标签修饰 位置:普通代 ...

  2. java代码块的理解

    最近在复习java基础,在看到java代码块的时候,忽然发现自己貌似对于java代码块一无所知,于是赶紧对着一些资料实战演练了一把. 对于java代码块,不难根据名称看出其实就是一些java语句的集合 ...

  3. java代码块执行顺序

    父类 public class Father { public Father() { System.out.println("父类构造PUBLIC father"); } stat ...

  4. 夯实Java基础系列7:一文读懂Java 代码块和执行顺序

    目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...

  5. 夯实Java基础系列7:Java 代码块和执行顺序

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  6. Java 代码块详解

    注:本文出自博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 注:本文原链接:https://www.cnblogs.com/chloneda/p/java-c ...

  7. java代码块 静态、非静态

    Java虚拟机的内存分区:Java栈.堆.方法区.本地方法栈.PC寄存器.还有一个常量池的概念,虚拟机会为每种类型分配一个常量池,而不是实例. 例如有一个类有很多子类,那么在父类定义的final变量, ...

  8. Java——代码块

    前言 在程序编写之中可以直接使用{...}定义的一段语句就是代码块.根据代码块的位置以及关键字的不同可以分为4种:普通代码块.构造块.静态块以及同步代码块(多线程相关).下面将先介绍前3种以及Java ...

  9. 08-02 Java 代码块,代码块执行的先后顺序问题

    代码块 /* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代 ...

随机推荐

  1. 将gdal源码转化为VS工程编译过程记录

    作者:朱金灿 来源:http://blog.csdn.net/clever101 为什么要用VS工程的方式来编译gdal库?主要还是为了调试方便,虽然理论上使用命令行方式生成库也能调试,详见:GDAL ...

  2. 新世界PT850/PT853检查用友机对接T1交易宝

    新世界PT850/PT853检查用友机对接T1交易宝 这是一个老话题.简单.条形码号码模式是没有必要说,我要说的是,,启用条码扫描.显示有关信息. 并能够产生:条码 , 数量,价格格 这样做的目的.将 ...

  3. 微信公众平台消息接口开发(31)微信浏览器HTTP_USER_AGENT判断

    微信公众平台开发 微信公众平台开发者 微信公众平台开发模式 微信浏览器 HTTP_USER_AGENT作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/archiv ...

  4. 线性滤波器(linear filter)与非线性滤波器(non-linear filter)

    1. 均值滤波器与中值滤波器 image processing - Difference between linear and non linear filter - Signal Processin ...

  5. [OpenGL]OpenGL坐标系和坐标变换

    OpenGL通过摄像机的模拟.要实现一个三维计算机图形重大转变,这是几何变换(模型转换-查看转型(两者统称为几何变换)).投影.作物转型.口变换等.同一时候,OpenGL还实现了矩阵堆栈等.理解掌握了 ...

  6. ASP.NET Core 基础教程 - ASP.NET Core 基础教程 - 简单教程,简单编程

    原文:ASP.NET Core 基础教程 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core 是对 ASP.NET 有重大意义的一次重新设计.本章节我们将介绍 A ...

  7. matlab 矢量化编程(三) —— 软阈值函数

    dj,k^=⎧⎩⎨⎪⎪dj,k−λ,dj,k≥λ0,otherwisedj,k+λ,dj,k≤−λ function y = soft(x, T) y = (x - abs(T) > 0) .* ...

  8. 最简单的IdentityServer实现——IdentityServer

    1.新建项目 新建ASP .Net Core项目IdentityServer.EasyDemo.IdentityServer,选择.net core 2.0   1   2 引用IdentitySer ...

  9. OnPropertyChanged的使用

    #region INotifyPropertyChanged         public event PropertyChangedEventHandler PropertyChanged;     ...

  10. cordova-plugin-local-notifications发送Android本地消息

    原文:cordova-plugin-local-notifications发送Android本地消息 1.GitHub源代码地址: https://github.com/katzer/cordova- ...