根据代码块出现的位置以及关键字分为以下四种代码块
普通代码块
定义在方法中的代码块
我们来观察下面两段代码
public class TestMethod {
public static void main(String[] args) {
{
//普通代码块
int a = 10;
System.out.println(a);
}
int a = 20;
System.out.println(a);
}
}
运行结果为:
public class TestMethod {
public static void main(String[] args) {
int a = 20;
{
//普通代码块
int a = 10;
System.out.println(a);
}
System.out.println(a);
}
}
运行结果为:
分析:
在第一段代码中,当普通代码块中的a = 10打印完之后,普通代码块就失效了,所以会认为a还没有定义过;在第二段代码中当a先赋值为20,然后在普通代码块中再次定义时,会出错,显示这个变量已经被定义过。
构造块
定义在类中的代码块(不加任何修饰),在对象产生时,构造块优先于构造方法执行,有几个对象产生,就调用几次构造块。
构造块的应用场景:应用于在构造方法执行前完成一些属性的初始化操作。
class Person{
public Person(){
System.out.println("1.Person类的构造方法");
}
{
//构造块
System.out.println("2.Person类的构造块");
}
}
public class TestMethod {
public static void main(String[] args) {
new Person();
new Person();
}
}
运行结果为:
静态代码块
静态代码块分为两类:非主类中的的静态代码块和主类中的静态代码块
1.非主类中的静态代码块
非主类中的静态代码块指没有被public关键字修饰的类中的静态代码块,在类加载时执行,优先于构造块执行,无论有多少对象产生,只会调用一次。
class Person{
public Person(){
System.out.println("1.Person类的构造方法");
}
{
//构造块
System.out.println("2.Person类的构造块");
}
static{
//静态代码块
System.out.println("3.Person类的静态代码块");
}
}
public class TestMethod {
public static void main(String[] args) {
new Person();
new Person();
}
}
运行结果为:
我们来思考以下几种情况:
当main方法中没有用到类时,结果是什么?
class Person{
public Person(){
System.out.println("1.Person类的构造方法");
}
{
//构造块
System.out.println("2.Person类的构造块");
}
static{
//静态代码块
System.out.println("3.Person类的静态代码块");
}
}
public class TestMethod {
public static void main(String[] args) {
}
}
运行结果为:
原因是没有加载类,也没有对象产生,所以什么也不打印
如果用到了类,却没有产生对象呢?
class Person{
static int a;
public Person(){
System.out.println("1.Person类的构造方法");
}
{
//构造块
System.out.println("2.Person类的构造块");
}
static{
//静态代码块---被static修饰的代码块
System.out.println("3.Person类的静态代码块");
}
}
public class TestMethod{
public static void main(String[] args){
System.out.println(Person.a);
}
}
运行结果为:
主类中的静态代码块
主类中的静态代码块优先于主方法执行,其他和非主类中的静态代码块一样
class Person{
public Person(){
System.out.println("1.Person类的构造方法");
}
{
//构造块
System.out.println("2.Person类的构造块");
}
static{
//静态代码块---被static修饰的代码块
System.out.println("3.Person类的静态代码块");
}
}
public class TestMethod{
static{
System.out.println("4.主类中的静态代码块");
}
public static void main(String[] args){
}
}
运行结果为:
同步代码块
同步代码块出现在多线程问题中,指使用synchronizd(内键锁)对代码块进行加锁操作,为了在同一时刻只有一个线程能够执行同步代码块。如果要使用同步代码块必须要锁定一个对象,一般可以锁定当前对象this
class MyThread implements Runnable {
private int ticket = 1000 ; // 一共十张票
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
// 在同一时刻,只允许一个线程进入代码块处理
synchronized(this) { // 表示为程序逻辑上锁
if(this.ticket>0) { // 还有票
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 模拟网络延迟
System.out.println(Thread.currentThread().getName()+",还有"
+this.ticket -- +" 张票");
}
}
}
}
}
public class TestDemo {
public static void main(String[] args) {
MyThread mt = new MyThread() ;
Thread t1 = new Thread(mt,"黄牛A");
Thread t2 = new Thread(mt,"黄牛B");
Thread t3 = new Thread(mt,"黄牛C");
t1.start();
t2.start();
t3.start();
}
}