java代码块牛刀小试
牛刀小试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代码块牛刀小试的更多相关文章
- Java代码块详解
Java中代码块指的是用 {} 包围的代码集合,分为4种:普通代码块,静态代码块,同步代码块,构造代码块 普通代码块: 定义:在方法.循环.判断等语句中出现的代码块 修饰:只能用标签修饰 位置:普通代 ...
- java代码块的理解
最近在复习java基础,在看到java代码块的时候,忽然发现自己貌似对于java代码块一无所知,于是赶紧对着一些资料实战演练了一把. 对于java代码块,不难根据名称看出其实就是一些java语句的集合 ...
- java代码块执行顺序
父类 public class Father { public Father() { System.out.println("父类构造PUBLIC father"); } stat ...
- 夯实Java基础系列7:一文读懂Java 代码块和执行顺序
目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...
- 夯实Java基础系列7:Java 代码块和执行顺序
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- Java 代码块详解
注:本文出自博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 注:本文原链接:https://www.cnblogs.com/chloneda/p/java-c ...
- java代码块 静态、非静态
Java虚拟机的内存分区:Java栈.堆.方法区.本地方法栈.PC寄存器.还有一个常量池的概念,虚拟机会为每种类型分配一个常量池,而不是实例. 例如有一个类有很多子类,那么在父类定义的final变量, ...
- Java——代码块
前言 在程序编写之中可以直接使用{...}定义的一段语句就是代码块.根据代码块的位置以及关键字的不同可以分为4种:普通代码块.构造块.静态块以及同步代码块(多线程相关).下面将先介绍前3种以及Java ...
- 08-02 Java 代码块,代码块执行的先后顺序问题
代码块 /* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代 ...
随机推荐
- Unable to find a single main class from the following candidates
关于start-class,spring boot官方手册是这么说明的: The plugin rewrites your manifest, and in particular it manages ...
- Tagging Physical Resources in a Cloud Computing Environment
A cloud system may create physical resource tags to store relationships between cloud computing offe ...
- WPF中3D旋转的实现
原文:WPF中3D旋转的实现 关于3D旋转的原理,请看Daniel Lehenbauer的文章 <Rotating the Camera with the Mouse> http://vi ...
- 机器学习 vs. 深度学习
1. bias/vairance Trend # 1:Scale driving Deep Learning process. 2. feature learning 的方式 A common com ...
- 统计web訪问前10的ip
cat access.log|awk '{print $0}'|sort|uniq -c|sort -nr|head -n 10
- MVC 添加数据的三种方法
1 通过Request接收数据,进行添加 <%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<d ...
- MEF 插件式开发 - WPF 初体验
原文:MEF 插件式开发 - WPF 初体验 目录 MEF 在 WPF 中的简单应用 加载插件 获取元数据 依赖注入 总结 MEF 在 WPF 中的简单应用 MEF 的开发模式主要适用于插件化的业务场 ...
- delphi判断线程状态函数(使用GetExitCodeThread API函数去判断线程的句柄)
//判断线程是否释放//返回值:0-已释放:1-正在运行:2-已终止但未释放://3-未建立或不存在 function CheckThreadFreed(aThread: TThread): Byte ...
- 原生Js监听普通dom尺寸变化
原生Js监听普通dom尺寸变化 具体做法有以下几种: 初始化项目后,轮询,反复查看 dom 尺寸是否变化,这种一听就感觉不好,开销太大. 监听元素的滚动事件,在 目标 dom 里面包裹一个同等大小的 ...
- Ionic2开发环境搭建-VS 2017
原文:Ionic2开发环境搭建-VS 2017 目前在VS 2017中创建Ionic2版本项目 注:在VS中开发Ionic项目,使用的Ionic(v2.x),Cordova(v6.3.1),Angul ...