1.代碼塊的基本介紹
- 代碼塊又稱初始化塊,屬于類中的成員(即是類的一部分)類似于方法,將邏輯語句封裝在方法體中,通過{ }包圍起來。
- 但和方法不同,沒有方法名,沒有返回,沒有參數(shù),只有方法體,而且不用通過對象或類顯式調用,而是加載類時,或創(chuàng)建對象時隱式調用
2.代碼塊的基本語法
[修飾符]{
代碼
};
注意:
- 修飾符可選,要寫的話,也只能寫static。
- 代碼塊分為兩類,使用static修 飾的叫靜態(tài)代碼塊,沒有static修飾的,叫普通代碼塊/非靜態(tài)代碼塊。
- 邏輯語句可以為任何邏輯語句(輸入,輸出,方法調用,循環(huán),判斷)。
- 分號可以寫,也可以省略。
3.代碼塊的好處:
1.相當于另外一種形式的構造器(對構造器的補充機制),可以做初始化操作。
2.場景:如果多個構造器中有重復的語句,可以抽取到初始化帶塊中,提高代碼的重復率。
4.實例(普通代碼塊):
三個構造器都有重復的語句,看起來特別的多余.
public class codeblock01 {
public static void main(String[] args) {
book book = new book("數(shù)據(jù)結構與算法");
System.out.println("========================");
book book1 = new book("kali從入門到入獄", 100, "呀吖呀");
}
}
class book{
private String name;
private double price;
private String author;
//3個構造器,構成了重載
public book(String name) {
System.out.println("書被打開了");
System.out.println("書被合上了");
System.out.println("構造器public book(String name)被調用");
this.name = name;
}
public book(String name, double price) {
System.out.println("書被打開了");
System.out.println("書被合上了");
this.name = name;
this.price = price;
}
public book(String name, double price, String author) {
System.out.println("書被打開了");
System.out.println("書被合上了");
System.out.println("構造器public book(String name, double price, String author)被調用");
this.name = name;
this.price = price;
this.author = author;
}
}
可以把一樣的語句放到一個代碼塊中即可當我們不管調用哪個構造器,創(chuàng)建對象,都會調用代碼塊中的代碼
public class codeblock01 {
public static void main(String[] args) {
book book = new book("數(shù)據(jù)結構與算法");
System.out.println("========================");
book book1 = new book("kali從入門到入獄", 100, "呀吖呀");
}
}
class book{
private String name;
private double price;
private String author;
//3個構造器,構成了重載
//三個構造器都有重復的語句,看起來特別的多余
//可以把一樣的語句放到一個代碼塊中即可
{
System.out.println("書被打開了");
System.out.println("書被合上了");
}
public book(String name) {
//System.out.println("書被打開了");
//System.out.println("書被合上了");
System.out.println("構造器public book(String name)被調用");
this.name = name;
}
public book(String name, double price) {
//System.out.println("書被打開了");
//ystem.out.println("書被合上了");
this.name = name;
this.price = price;
}
public book(String name, double price, String author) {
//System.out.println("書被打開了");
//System.out.println("書被合上了");
System.out.println("構造器public book(String name, double price, String author)被調用");
this.name = name;
this.price = price;
this.author = author;
}
}
上面兩個例子的運行結果都是:
書被打開了
書被合上了
構造器public book(String name)被調用
========================
書被打開了
書被合上了
構造器public book(String name, double price, String author)被調用
說明:代碼塊的調用是優(yōu)先于構造器的!
5.靜態(tài)代碼塊
static代碼塊叫靜態(tài)代碼塊,作用是對類進行初始化它隨著類的加載進行初始化,而且隨著類的加載而被執(zhí)行并且只會執(zhí)行一次,如果是普通代碼塊,每次創(chuàng)建一個對象就執(zhí)行一次。
實例①:
public class Test001 {
public static void main(String[] args) {
A a = new A();
}
}
class A{
//靜態(tài)代碼塊
static {
System.out.println("A的靜態(tài)代碼塊正在被執(zhí)行");
}
}
運行結果:
A的靜態(tài)代碼塊正在被執(zhí)行
得到結論
創(chuàng)建對象實例的時候也就是new的時候。
實例②:
public class Test002 {
public static void main(String[] args) {
A a = new A();
}
}
class A extends B{
//靜態(tài)代碼塊
static {
System.out.println("A的靜態(tài)代碼塊正在被執(zhí)行");
}
}
class B {
static {
System.out.println("B的靜態(tài)代碼塊正在被執(zhí)行");
}
}
運行結果:
B的靜態(tài)代碼塊正在被執(zhí)行
A的靜態(tài)代碼塊正在被執(zhí)行
得到結論
創(chuàng)建子類對象實例,父類也會被加載,父類先被加載,子類后被加載。
實例③:
public class Test003 {
public static void main(String[] args) {
System.out.println(C.n1);
}
}
class C{
public static int n1 = 10000;
static {
System.out.println("C的靜態(tài)代碼塊正在被執(zhí)行");
}
}
運行結果:
C的靜態(tài)代碼塊正在被執(zhí)行
1000
得到結論
使用類的靜態(tài)成員時,例如:靜態(tài)成員,靜態(tài)方法。靜態(tài)代碼塊也要進行加載。
實例④:
public class Test004 {
public static void main(String[] args) {
D d = new D();
D d1 = new D();
}
}
class D{
static {
System.out.println("D的靜態(tài)代碼塊被調用");
}
{
System.out.println("D的普通代碼塊被調用");
}
}
運行結果:
D的靜態(tài)代碼塊被調用
D的普通代碼塊被調用
D的普通代碼塊被調用
說明:
靜態(tài)代碼塊作用是對類進行初始化它隨著類的加載進行初始化,而且隨著累的加載而被執(zhí)行并且只會執(zhí)行一次,
如果是普通代碼塊,每次創(chuàng)建一個對象就執(zhí)行一次。
實例⑤:
public class Test005 {
public static void main(String[] args) {
System.out.println(D.n1);
}
}
class D{
public static int n1 = 10000;
static {
System.out.println("D的靜態(tài)代碼塊被調用");
}
{
System.out.println("D的普通代碼塊被調用");
}
}
運行結果:
D的靜態(tài)代碼塊被調用
10000
說明
普通代碼塊需要在new對象的時候才會被調用,而且是每次創(chuàng)建新對象就會被調用。
而靜態(tài)代碼塊,只要類加載了就會被調用。
6.類什么時候被加載?
- 創(chuàng)建對象實例的時候也就是new的時候。
- 創(chuàng)建子類對象實例,父類也會被加載,父類先被加載,子類后被加載。
- 使用類的靜態(tài)成員時,例如:靜態(tài)成員,靜態(tài)方法。
7.創(chuàng)建一個對象時,在一個類中,調用順序是怎么樣的
- 先調用靜態(tài)代碼塊和靜態(tài)屬性初始化。靜態(tài)代碼塊和靜態(tài)屬性初始化調用的優(yōu)先級一樣,如果有多個靜態(tài)代碼和多個靜態(tài)變量初始化,就按照定義的順序執(zhí)行。
- 調用普通代碼塊和普通屬性的初始化。普通代碼塊和普通屬性的優(yōu)先級一樣,這個和上面的一樣。
3)最后在調用構造方法。
實例⑥:
public class codeblock03 {
public static void main(String[] args) {
AS as = new AS();
}
}
class AS{
static {
System.out.println("AS的靜態(tài)代碼塊被調用");
}
private static int n1 = getN1();
public static int getN1(){
System.out.println("getN1方法被調用");
return 10000;
}
private int n2 = getN2();
public int getN2(){
System.out.println("getN2方法被調用");
return 90000;
}
{
System.out.println("AS的普通代碼塊被調用");
}
public AS(){
System.out.println("無參構造器被調用");
}
}
運行結果:
AS的靜態(tài)代碼塊被調用
getN1方法被調用
getN2方法被調用
AS的普通代碼塊被調用
無參構造器被調用
8.存在繼承關系時候調用的順序
- 父類的靜態(tài)代碼塊和靜態(tài)屬性(優(yōu)先級一樣)。
- 子類的靜態(tài)代碼塊和靜態(tài)屬性(優(yōu)先級一樣)。
- 父類的普通代碼塊和普通屬性初始化。
- 父類的構造方法。
- 子類的普通代碼塊和子類的普通屬性初始化。
- 子類的構造方法。
注意: 靜態(tài)代碼塊只能直接調用靜態(tài)成員,普通代碼塊可以調用任意成員
實例⑦:
public class codeblock04 {
public static void main(String[] args) {
ZL zl = new ZL();
}
}
class ZL extends FL{
private static int A = getA();
private int A1 = getA1();
public static int getA(){
System.out.println("子類的靜態(tài)方法被調用");
return 111;
}
public int getA1(){
System.out.println("子類的普通方法被調用");
return 222;
}
static {
System.out.println("子類的靜態(tài)代碼塊被調用");
}
{
System.out.println("子類的普通代碼塊被調用");
}
public ZL(){
System.out.println("子類的構造器被調用");
}
}
class FL{
private static int B = getB();
private int B1 = getB1();
public static int getB(){
System.out.println("FL父類的靜態(tài)方法被調用");
return 888;
}
public int getB1(){
System.out.println("FL父類的普通方法被調用");
return 999;
}
static {
System.out.println("FL父類的靜態(tài)代碼塊被調用");
}
{
System.out.println("FL父類的普通代碼塊被調用");
}
public FL() {
System.out.println("FL父類的構造器被調用");
}
}
運行結果:
FL父類的靜態(tài)方法被調用
FL父類的靜態(tài)代碼塊被調用
子類的靜態(tài)方法被調用
子類的靜態(tài)代碼塊被調用
FL父類的普通方法被調用
FL父類的普通代碼塊被調用
FL父類的構造器被調用
子類的普通方法被調用
子類的普通代碼塊被調用
子類的構造器被調用