夯实Java基础(八)——代码块
在Java中代码块指的是使用”{}”括起来的代码称为代码块。代码块一共分为4种:局部代码块,静态代码块,同步代码块,构造代码块。
1、局部代码块
局部代码块就是定义在方法体内部的代码块。
public class CodeBlockTest {
public static void main(String[] args) {
int i;
{
i=10;
System.out.println("局部代码块"+i);
int j=20;
System.out.println("局部代码块"+j);
}
System.out.println(i);
//Cannot resolve symbol 'j'
//System.out.println(j);
}
}
可以看到,在局部代码块中声明的变量,只能在局部代码块中进行访问。局部代码块可以操作非局部代码块的变量,但是非局部代码块不能访问局部代码块的变量。这就起到了很好的分隔,就可以用来限制局部变量的生命周期,及早释放,提高内存利用率。如果有多个局部代码块,则按照它们定义的先后顺序执行。
2、静态代码块
静态代码块就是在类中用static关键字修饰的代码块,它不能出现在方法体或者代码块内,我在上一篇的Static关键字中也记录了静态代码块的使用,所以就把那里的例子引用过来了。
被static修饰的代码块也叫静态代码块,会随着JVM加载类的时候而加载这些静态代码块,并且会自动执行。它们可以有多个,可以存放在于该类的任何地方(不能放在方法内部)。JVM会按照它们的先后顺序依次执行它们,而且每个静态代码块只会被初始化一次,不会进行多次初始化。
简单示例:
public class Person{
static {
System.out.println("Person类静态块");
}
public Person() {
System.out.println("Person类构造器");
}
public static void main(String[] args) {
new Son();
System.out.println("-------");
new Son();
}
}
class Son extends Person{
static {
System.out.println("Son类静态块");
}
public Son() {
System.out.println("Son类构造器");
}
}
运行结果:

从运行结果分析:首先运行main()方法,然后JVM就会加载类,因为Son类继承了Person类,所以会先加载父类Person类,再去加载子类Son。由于静态代码块会随着类的加载而加载,所以先输出父类中静态代码块内容"Person类静态块",然后输出子类中静态代码块内容"Son类静态块"。加载完类之后执行main()方法内容,先new了第一个Son实例,由于子类构造器中默认调用了super(),所以先输出父类构造器的内容,再输出子类构造器的内容。之后又new了第二个Son实例,却是输出的构造器的内容,说明static静态块只加载了一次。结论:静态代码块是先加载父类的静态代码块,然后再加载子类静态代码块,是随着类的加载而加载,而且只会加载一次。
补充:因为入口main()是个方法,也需要用类去调用,所以类的加载优先级>main()方法。
3、同步代码块
是使用synchronized关键字修饰的普通代码块(其只能用在方法内部)。其作用在多线程的环境下,对共享数据进行加锁, 从而实现线程同步,是一种多线程保护机制。
public void show(){
synchronized (obj){
System.out.println("同步代码块");
}
}
4、构造代码块
直接在类中用"{}"定义且不加任何关键字的代码块成为构造代码块。
public class CodeBlockTest {
{
System.out.println("构造代码块...");
}
public CodeBlockTest() {
System.out.println("无参构造器...");
}
public static void main(String[] args) {
new CodeBlockTest();
new CodeBlockTest();
}
}
运行结果:

从运行结果容易看出,在创建对象时,构造代码块才会被执行,而且优先于构造方法执行(这里和构造块写前写后没关系,将构造块写在构造方法后面也是一样的结果)。而且每当有对象被创建的时,都会执行构造代码块。如果存在多个构造代码块,则执行顺序按照定义顺序依次执行。
构造代码块的作用:可以用来初始化实例变量和实例环境(即创建对象的必要条件),这样不仅可以减少代码量,同时也可以增强程序的可读性。
注意:构造代码块并不是真正的在构造方法之前执行的,JVM在编译的时候会把构造代码块插入到每个构造函数的最前面,构造代码块随着构造方法的执行而执行,如果某个构造方法调用了其他的构造方法,那么构造代码块不会插入到该构造方法中以免构造代码块执行多次。我们可以从编译生成的class文件可以看出来。

5、代码块的执行顺序
上面讲述了四种代码块的基本信息,然后我们来看一下四种代码块的执行顺序。
public class CodeBlockTest {
static {
System.out.println("静态代码块...");
}
{
System.out.println("构造代码块...");
}
public CodeBlockTest() {
System.out.println("无参构造器...");
}
public void show(){
{
System.out.println("局部代码块...");
}
}
public static void main(String[] args) {
System.out.println("main()方法运行");
new CodeBlockTest().show();
System.out.println("----------");
new CodeBlockTest().show();
}
}
打印结果:

执行顺序(优先级从高到低):静态代码块>mian()方法>构造代码块>构造方法>局部代码块。其中静态代码块只执行一次。构造代码块和局部代码块再每次创建对象是都会执行。
夯实Java基础(八)——代码块的更多相关文章
- Java基础(basis)-----代码块详解
1.静态代码块 格式: static{ 内容..... } 随着类的加载而加载,而且只被加载一次 多个静态代码块之间按照顺序结构执行 优先其他各种代码块以及构造函数先执行 静态的代码块中只能执行静态的 ...
- Java基础学习-代码块
/*代码块: * 用{}修饰的代码 * 1.局部代码块:控制变量,存在方法中,控制变量的生命周期(作用域) * 2.构造代码块:提取构造方法中的共性,每次创建对象,都会执行,并且在构造方法执行之前执行 ...
- 夯实Java基础系列7:一文读懂Java 代码块和执行顺序
目录 Java中的构造方法 构造方法简介 构造方法实例 例 1 例 2 Java中的几种构造方法详解 普通构造方法 默认构造方法 重载构造方法 java子类构造方法调用父类构造方法 Java中的代码块 ...
- 夯实Java基础系列7:Java 代码块和执行顺序
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...
- 【Java基础】2、Java中普通代码块,构造代码块,静态代码块区别及代码示例
Java中普通代码块,构造代码块,静态代码块区别及代码示例.Java中普通代码块,构造代码块,静态代码块区别及代码示例 执行顺序:静态代码块>静态方法(main方法)>构造代码块>构 ...
- 夯实Java基础系列目录
自进入大学以来,学习的编程语言从最初的C语言.C++,到后来的Java,. NET.而在学习编程语言的同时也逐渐决定了以后自己要学习的是哪一门语言(Java).到现在为止,学习Java语言也有很长一段 ...
- 夯实Java基础系列5:Java文件和Java包结构
目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...
- 夯实Java基础系列6:一文搞懂抽象类和接口,从基础到面试题,揭秘其本质区别!
目录 抽象类介绍 为什么要用抽象类 一个抽象类小故事 一个抽象类小游戏 接口介绍 接口与类相似点: 接口与类的区别: 接口特性 抽象类和接口的区别 接口的使用: 接口最佳实践:设计模式中的工厂模式 接 ...
- 夯实Java基础系列9:深入理解Class类和Object类
目录 Java中Class类及用法 Class类原理 如何获得一个Class类对象 使用Class类的对象来生成目标类的实例 Object类 类构造器public Object(); register ...
- 夯实Java基础系列10:深入理解Java中的异常体系
目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...
随机推荐
- MyBatis从入门到精通(八):MyBatis动态Sql之foreach标签的用法
最近在读刘增辉老师所著的<MyBatis从入门到精通>一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解如何使用foreach ...
- 为什么我使用 Linux 开发
Linux 能用吗? 当我对 Linux 的印象似乎还停留在黑乎乎的命令行界面上的时候,我身边的一些朋友告诉我或者建议我使用 Linux 时,我会一脸惊讶的问他,那个怎么用(来开发或者日常使用)? L ...
- JPA自定义实体的id
背景:继上一篇文章,已经实现客户端数据库数据,存入服务器,但是,两张表的id不一样,应该是id设置自增了,所以虽然从客户端查出的实体带id,但是存入服务器时id被抹掉,按照服务端表的id序号向上自增, ...
- 《Python 3网络爬虫开发实战中文》超清PDF+源代码+书籍软件包
<Python 3网络爬虫开发实战中文>PDF+源代码+书籍软件包 下载: 链接:https://pan.baidu.com/s/18yqCr7i9x_vTazuMPzL23Q 提取码:i ...
- Java_Set用法总结
在java语言中,提供多种不同的结构来组织对象,Set(集合)是其中的一种,本身是一个接口,其迭代时的顺序取决于其具体实现. 典型的实现包括: HashSet:哈希表是通过使用称为散列法的机制来存储信 ...
- nio原理和示例代码
我正在为学习大数据打基础中,为了手撸rpc框架,需要懂得nio的原理,在搞懂nio框架前,我会带着大家手撸一些比较底层的代码,当然今后当我们学会了框架,这些繁琐的代码也就不用写了,但是学一学底层的代码 ...
- .NET Core 学习资料精选:入门
开源跨平台的.NET Core,还没上车的赶紧的,来不及解释了-- 本系列文章,主要分享一些.NET Core比较优秀的社区资料和微软官方资料.我进行了知识点归类,让大家可以更清晰的学习.NET Co ...
- python通过TimedRotatingFileHandler按时间切割日志
通过TimedRotatingFileHandler按时间切割日志 线上跑了一个定时脚本,每天生成的日志文件都写在了一个文件中.但是日志信息不可能输出到单一的一个文件中. 原因有二:1.日志文件越来越 ...
- C语言指针专题——如何理解指针
本文为原创,欢迎转发! 最近在研读C primer plus 5版中文版,老外写的,还是很经典的,推荐给读者们,有需要的朋友可以在这里购买:C primer plus 5版中文版 指针,传说中是C语言 ...
- [原创]MYSQL周期备份shell脚本
这个脚本是实现阿里云mysql数据库全量周期备份的shell脚本,实现备份数据按一周星期几分开存放.一下是脚本内容: #!/bin/bash echo `date`echo "backup ...