在java中一共有四个代码块,分别是静态代码块、非静态代码块(普通代码块)、构造块、同步代码块。尽管他们的名字叫法不同但是他们唯一的一个共同点是都用“{ }”括起来。笔者发现网上的文章解释的不够全面,故总结归纳了一番,如有错误欢迎拍砖。
1. 静态代码块
使用static关键字声明的代码块称为静态代码块。通常静态代码块比较常用,它主要用于为静态属性初始化,给类的静态变量赋初始值。静态代码块不存在任何方法体中,静态代码块在对象首次载入内存时执行,并且每个静态代码块只执行一次。静态代码块和静态方法一样,不能直接访问类的实例变量和实例方法,必须要实例的引用来访问它们。静态代码块优先于主方法执行,优先于构造块的执行。
package com.zyx.obj;
public class TestBlock {
public static void main(String[] args) {
new People(0, "zyx").Print();//匿名类
new People(1, "xyz").Print();//匿名类
}
}
class People {
private int age;
private String name;
static{
System.out.println("这是一个静态代码块,只执行一次");
}
public People(int age, String name) {
this.age = age;
this.name = name;
System.out.println("这是一个构造方法");
}
void Print() {
System.out.println("姓名" + this.name + "年龄" + this.age);
}
static void Eat() {
System.out.println("人类需要吃饭!");
}
}
输出的结果是:这是一个静态代码块,只执行一次
这是一个构造方法
姓名zyx年龄0
这是一个构造方法
姓名xyz年龄1
这是一个构造方法
姓名zyx年龄0
这是一个构造方法
姓名xyz年龄1
2. 非静态代码块(普通代码块)
没有使用static关键字声明的代码块称为非静态代码块(普通代码块)。
普通代码块必须存在于方法中,只有写在方法中才叫普通代码块,如果写在了类中就是构造代码块了。
public static void main(String[] args) {
int a =0;
{
System.out.println("我是普通代码块");
a=a+10;
}
System.out.println("执行主方法了");
System.out.println("a的值是"+a);
}
输出的结果是:我是普通代码块
执行主方法了
a的值是10
3.构造块
简而言之,就是把普通代码块写到了类里,它的名字就变成构造块了。PS:看吧~把同样的一个事物摆在不同的台面,会带来不同的影响。你们都确定自己摆对了位置吗?
package com.zyx.obj;
public class TestBlock {
public static void main(String[] args) {
new People(0, "zyx").Print();// 匿名类
new People(1, "xyz").Print();// 匿名类
}
}
class People {
private int age;
private String name;
{
System.out.println("这是一个普通的代码块");
}
static {
System.out.println("这是一个静态代码块,只执行一次");
}
public People(int age, String name) {
this.age = age;
this.name = name;
System.out.println("这是一个构造方法");
}
void Print() {
System.out.println("姓名" + this.name + "年龄" + this.age);
}
}
在java中构造块与构造方法执行相同的次数,但是构造块优先于构造方法。在执行时的先后顺序为:静态块(仅执行一次)
——>构造块——>构造方法
——>普通代码块(这个是要看普通代码块的位置,可忽略)
4.同步代码块(用于多线程)
如果在普通代码模块前面加上synchronized关键字,则此代码块就成为了同步代码块。
格式为:
synchronized(同步对象){
需要同步的代码
}
同步对象一般为当前对象,即使用this关键字。
package com.zyx.obj;
public class CisFor同步代码块 {
public static void main(String args[]) {
Demo d = new Demo();
Thread t1 = new Thread(d, "售票点 A");
Thread t2 = new Thread(d, "售票点 B");
Thread t3 = new Thread(d, "售票点 C");
t1.start();
t2.start();
t3.start();
}
}
class Demo implements Runnable {
private int ticket = 10;
public void run() {
while (ticket > 0) {
// 加入同步块
synchronized (this) {
if (this.ticket > 0) {
try {
Thread.sleep(100);
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName()
+ " --> 卖票:" + this.ticket--);
}
}
}
}
};
由于多线程结果没有标准,故不列出结果。