静态代码块,普通代码块,同步代码块,构造代码块和构造函数解

构造函数
用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种。
特点:
1:该函数的名称和所在类的名称相同。
2:不需要定义返回值类型。
3:该函数没有具体的返回值。
记住:所有对象创建时,都需要初始化才可以使用。

注意事项:一个类在定义时,如果没有定义过构造函数,那么该类中会自动生成一个空参数的构造函数,为了方便该类创建对象,完成初始化。如果在类中自定义了构造函数,那么默认的构造函数就没有了。

一个类中,可以有多个构造函数,因为它们的函数名称都相同,所以只能通过参数列表来区分。所以,一个类中如果出现多个构造函数。它们的存在是以重载体现的。

构造函数和一般函数有什么区别呢?
1:两个函数定义格式不同。
2:构造函数是在对象创建时,就被调用,用于初始化,而且初始化动作只执行一次。
    一般函数,是对象创建后,需要调用才执行,可以被调用多次。
   
什么时候使用构造函数呢?
分析事物时,发现具体事物一出现,就具备了一些特征,那就将这些特征定义到构造函数内。

构造代码块和构造函数有什么区别?
构造代码块:是给所有的对象进行初始化,也就是说,所有的对象都会调用一个代码块。只要对象一建立。就会调用这个代码块。
构造函数:是给与之对应的对象进行初始化。它具有针对性。

普通代码块

  直接在一个方法中出现的{}就称为普通代码块,例子程序如下:
复制代码
  public class CodeDemo01{

  public static void main(String[] args){

  //普通代码块

  {

  int x = 10;

  System.out.println("x=" + x);

  }

  int x = 100;

  System.out.println("x=" + x);

  }

 
复制代码
构造代码块

  直接在类中定义的没有加static关键字的代码块{}称为构造代码块,例子程序如下:

复制代码
  public class CodeDemo02{

  public CodeDemo02(){

  System.out.println("========这是构造方法=========");

  }

  //这是构造代码块,而且在new对象时,构造代码块优先构造方法执行

  {

  System.out.println("=========这是构造块!=========");

  }

  public static void main(String[] args){

  new CodeDemo02();

  new CodeDemo02();

  }

  }
复制代码
静态代码块
就是一个有静态关键字标示的一个代码块区域。定义在类中。

  使用static关键字声明的代码块称为静态代码块,静态块的主要目的是用来为静态属性初始化,例子程序如下:
 
复制代码
 public class CodeDemo03

  {

  static{

  System.out.println("这是主类中的静态代码块!");

  }

  public static void main(String[] args){

  new Demo();

  new Demo();

  new Demo();

  }

  }

  class Demo

  {

  static{

  System.out.println("这是Demo类中的静态代码块!");

  }

  {

  System.out.println("这是Demo类中的构造块!");

  }

  public Demo(){

  System.out.println("这是构造方法!");

  }

  }
复制代码
静态块优先于主方法的执行,静态块优先于构造方法的执行,而且只执行一次!

作用:可以完成类的初始化。
静态代码块随着类的加载而执行,而且只执行一次(new 多个对象就只执行一次)。如果和主函数在同一类中,优先于主函数执行。
静态块的特点是在类加载的时候就执行,先说一下类加载,一个程序要想运行,首先要把代码加载到内存中对吧?然后才能去和CPU交流,
这是冯诺依曼计算机规定的。Java也是一样,Java的.class字节码文件要想执行,首先也要加载到内存,由类加载器把字节码文件的代码加载到内存中,这一步就叫类加载,这是首先要进行的。
public class Test {
static {
System.out.println("我是静态块");
}
}
当创建Test类的一个对象的时候,比如new Test() ,是这样,首先是类加载,然后才能new对象,静态块在类加载的时候就执行了,
这就说明静态块在new对象之前就会执行,而且一个类在第一次被使用的时候会被加载,然后在整个应用程序的生命周期当中不会再次被加载了,就加载这一次,所以这就说明,静态块就执行一次,不会执行第二遍!
复制代码
public class Test {
public Test() {// 构造方法
System.out.println("我是构造方法,创建对象的时候我会执行,我执行完,对象就造出来了");
}

static {
System.out.println("我是静态块,类加载的时候我就执行了,而且只执行这一次");
}
}
复制代码
然后这样:
new Test();
new Test();
你会发现首先打印出静态块的信息,然后才打印出构造方法信息,然后再次new Test();的时候,只打印出了构造方法的信息,这个例子证明了我上面说的是对的!

这就是静态块,静态块中初始化Map。
下面就可以说是在静态块中初始化Map,
public class Test {
private static Map m;
static {
m = new HashMap();
}
}
静态代码块是当类在加载时,静态代码块就会被自动执行,先于main方法被执行且只执行一次,常用来对一些类的属性进行初始化
构造代码块是每次进行对象的建立时都会被执行到

同步代码块。
如果在代码块前加上 synchronized关键字,则此代码块就成为同步代码块。
同步代码块的格式:
synchronized(同步对象){
需要同步的代码;
}
同步对象一般为当前对象,即使用this关键字
复制代码
package cn.sunzn.synchronize;

public class SynchronizeCode {
   public static void main(String[] args) {
       new Thread() {
           public void run() {
               while (true) {
                   System.out.println("同步代码");
               }
           };
       }.start();
       new Thread() {
           public void run() {
               while (true) {
                   System.out.println("SynchronizeCode");
               }
           };
       }.start();
   }
}
复制代码

结果为:

复制代码
SynchronizeCode
SynchronizeCode
SynchronizeCode
SynchronizeCode
同步代码
同步代码
同步代码
同步代码
复制代码
静态代码块、构造代码块、构造函数同时存在时的执行顺序
静态代码块 -->构造代码块 --> 构造函数;
也就是 先执行静态代码块,接着就是构造代码块。再接着就是构造函数。如果在主类里面的话。执行顺序是:先执行静态代码块。在执行main方法、在执行构造代码块。在接着才是构造函数。
 
静态代码优先于非静态的代码,是因为被static修饰的成员都是类成员,会随着JVM加载类的时候加载而执行,而没有被static修饰的成员也被称为实例成员,需要创建对象才会随之加载到堆内存。所以静态的会优先非静态的。 
执行构造器(构造方法)的时候,在执行方法体之前存在隐式三步: 
1,super语句,可能出现以下三种情况: 
1)构造方法体的第一行是this语句,则不会执行隐式三步, 
2)构造方法体的第一行是super语句,则调用相应的父类的构造方法, 
3)构造方法体的第一行既不是this语句也不是super语句,则隐式调用super(),即其父类的默认构造方法,这也是为什么一个父类通常要提供默认构造方法的原因; 
下面我们来一一验证这三种情况:
第一种情况:构造方法体的第一行是this语句,则不会执行隐式三步。

父类:
public class AA {
public AA(){
System.out.println("AA");
}
}

子类一:
public class BB extends AA {

	/**
	 * @param args
	 */
	public BB(){
		System.out.println("original Constructor BB");
	}
	public BB(String str){
		this();
		System.out.println(str+"Constructor BB");
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BB bb = new BB("second");
	}

}


子类二:
public class BB extends AA {

	/**
	 * @param args
	 */
	public BB(){
		System.out.println("original Constructor BB");
	}
	public BB(String str){
		//this();  
		System.out.println(str+"Constructor BB");
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BB bb = new BB("second");
	}

}


结果一:
AA
original Constructor BB
secondConstructor BB

结果二:
AA
secondConstructor BB

第二种情况:略

第三种情况:隐式调用super()

父类:
public class AA {
public AA(){
System.out.println("AA");
}
}

子类:
public class BB extends AA {

	/**
	 * @param args
	 */
	public BB(){
		System.out.println("BB");
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		BB bb = new BB();
	}

}


结果:
AA
BB

class Father {
{
System.out.println("父类构造块");// 3
}
static {
System.out.println("父类静态块");// 1
}


Father() {
System.out.println("父类构造函数");//4
}
}


public class Lianxi14 extends Father {
{
System.out.println("子类构造块");// 5
}
static {
System.out.println("子类静态块");// 2
}


Lianxi14() {
System.out.println("子类构造函数");//6
}


public static void main(String[] args) {
new Lianxi14();
}


}<span style="font-family:microsoft yahei;"><span style="font-size: 14px; line-height: 26px; background-color: rgb(255, 255, 255);">
</span></span>

执行顺序如下:

父类静态块
子类静态块
父类构造块
父类构造函数
子类构造块
子类构造函数



class X{
    Y y=new Y();
    public X(){
        System.out.print("X");
    }
}
class Y{
    public Y(){
        System.out.print("Y");
    }
}
public class Z extends X{
    Y y=new Y();
    public Z(){
        System.out.print("Z");
    }
    public static void main(String[] args) {
        new Z();
    }
}


初始化过程: 
1. 初始化父类中的静态成员变量和静态代码块 ; 
2. 初始化子类中的静态成员变量和静态代码块 ; 
3.初始化父类的普通成员变量和代码块,再执行父类的构造方法;
4.初始化子类的普通成员变量和代码块,再执行子类的构造方法; 
 
(1)初始化父类的普通成员变量和代码块,执行  Y y = new Y(); 输出Y 
(2)再执行父类的构造方法;输出X
(3) 初始化子类的普通成员变量和代码块,执行  Y y=new Y(); 输出Y 
(4)再执行子类的构造方法;输出Z
 所以输出YXYZ

 

                
### 回答1: Java 中有两种代码块,分别是静态代码块普通代码块。 1. 静态代码块 静态代码块会在类加载时执行,只会执行一次。通常用于初始化静态变量或对静态变量进行复杂的初始化操作。 静态代码块的语法如下: ``` static { // 静态代码块的代码 } ``` 2. 普通代码块 普通代码块也称为局部代码块或匿名代码块,它是定义在方法内部、语句块内部或者构造函数内部的代码块普通代码块在执行时会先于方法体内的语句执行,用于限定变量的生命周期或进行一些复杂的初始化操作。 普通代码块的语法如下: ``` { // 普通代码块的代码 } ``` ### 回答2: Java代码块主要分为普通代码块静态代码块构造代码块三种。 普通代码块是在方法或者类中的语句块,在运行时会按照顺序执行其中的代码。普通代码块没有修饰符,用{}括起来,可以在代码块中定义局部变量,作用域只限于代码块中。 静态代码块是在类加载时执行的代码块,用于初始化类的静态成员。静态代码块使用static修饰,也用{}括起来。它在类的加载过程中只被执行一次,并且优先于其他代码块构造方法执行,一般用于对静态变量进行赋值和初始化。 构造代码块也叫实例代码块,用于在创建对象时执行一些操作,比如给成员变量进行初始化。构造代码块用{}括起来,没有修饰符,每次创建对象时都会被执行,并且优先于构造方法执行。 这三种代码块的执行顺序为:静态代码块首先在类加载时被执行,紧接着是构造代码块,最后才是构造方法中的代码块普通代码块则可以在方法中的任意位置执行。 通过使用这些代码块,我们可以在程序的不同阶段进行一些特定操作和初始化工作,提高代码的灵活性和可维护性。 ### 回答3: 在Java中,代码块主要有以下几种使用种类: 1. 普通代码块(局部代码块):普通代码块是用花括号{}括起来的一段代码,在代码块中声明的变量只在此代码块中可见,出了代码块就不能被访问了。 2. 静态代码块静态初始化块):静态代码块是用static关键字定义的代码块,在类加载时会执行,只会执行一次。通常用来对静态变量进行初始化操作。 3. 构造代码块构造代码块在类中的成员方法外部定义,没有任何访问修饰符,会在构造函数执行之前执行。构造代码块可以用来初始化实例成员变量。 4. 同步代码块同步代码块用来修饰需要同步执行的代码,避免多线程同时访问共享资源造成的数据不一致问题。同步代码块使用synchronized关键字修饰,一次只能有一个线程进入同步代码块执行。 5. try-catch代码块:try-catch代码块用来捕获和处理异常。try代码块中包含可能会产生异常的代码,catch代码块中处理try代码块中抛出的异常,如果有多个catch代码块,会根据抛出的异常类型匹配处理。 以上是Java中常见的代码块使用种类,不同的代码块有不同的作用和使用场景,可以根据实际需求来选择合适的代码块
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值