Java基礎(chǔ)之構(gòu)造器、代碼塊、類(lèi)加載時(shí)機(jī)的用法詳解
1、構(gòu)造器細(xì)節(jié)
一個(gè)類(lèi)可以定義多個(gè)不同的構(gòu)造器,即構(gòu)造器重載;
- 比如:我們可以再給Person類(lèi)定義一個(gè)構(gòu)造器,用來(lái)創(chuàng)建對(duì)象的時(shí)候,只指定人名不需要指定年齡。
- 構(gòu)造器名和類(lèi)名要相同;
- 構(gòu)造器沒(méi)有返回值;
- 構(gòu)造器是完成對(duì)象的初始化,并不是創(chuàng)建對(duì)象;
- 在創(chuàng)建對(duì)象時(shí),系統(tǒng)自動(dòng)的調(diào)用該類(lèi)的構(gòu)造方法;
- 如果程序員沒(méi)有定義構(gòu)造器,系統(tǒng)會(huì)自動(dòng)給類(lèi)生成一個(gè)默認(rèn)無(wú)參構(gòu)造器(也叫默認(rèn)構(gòu)造器),比如
Dog (){}; - 一旦定義了自己的構(gòu)造器,默認(rèn)的構(gòu)造器就覆蓋了,就不能再使用默認(rèn)的無(wú)參構(gòu)造器,除非顯式的定義一下,即:
Dog0){}。
2、代碼塊細(xì)節(jié)
2.1 代碼塊
代碼化塊又稱(chēng)為初始化塊,屬于類(lèi)中的成員[即:是類(lèi)的一部分],類(lèi)似于方法,將邏輯語(yǔ)句封裝在方法體中,通過(guò)包圍起來(lái)。
但和方法不同,沒(méi)有方法名沒(méi)有返回,沒(méi)有參數(shù),只有方法體,而且不用通過(guò)對(duì)象或類(lèi)顯式調(diào)用,而是加載類(lèi)時(shí),或創(chuàng)建對(duì)象時(shí)隱式調(diào)用。
語(yǔ)法:
[修飾符]{
//代碼
}說(shuō)明注意:
1)修飾符可選,要寫(xiě)的話(huà),也只能寫(xiě) static;
2)代碼塊分為兩類(lèi),使用static修飾的叫靜態(tài)代碼塊,沒(méi)有static修飾的,叫普通代碼塊/非靜態(tài)代碼塊;
3)邏輯語(yǔ)句可以為任何邏輯語(yǔ)句(輸入、輸出、方法調(diào)用、循環(huán)、判斷等);
4)代碼塊尾部的;號(hào)可以寫(xiě)上,也可以省略。
理解:代碼塊相對(duì)于另一種形式的構(gòu)造器(對(duì)構(gòu)造器的補(bǔ)充機(jī)制),可以做初始化操作。
場(chǎng)景:如果多個(gè)構(gòu)造器中有重復(fù)語(yǔ)句,可以抽取到代碼塊中,提高代碼的復(fù)用性。
案例:
public class CodeBlock01 {
public static void main(String[] args) {
Movie movie = new Movie("你好,李煥英");
System.out.println("===============");
Movie movie2 = new Movie("唐探3", 100, "陳思誠(chéng)");
}
}
class Movie {
private String name;
private double price;
private String director;
//3個(gè)構(gòu)造器-》重載
//解讀
//(1) 下面的三個(gè)構(gòu)造器都有相同的語(yǔ)句
//(2) 這樣代碼看起來(lái)比較冗余
//(3) 這時(shí)我們可以把相同的語(yǔ)句,放入到一個(gè)代碼塊中,即可
//(4) 這樣當(dāng)我們不管調(diào)用哪個(gè)構(gòu)造器,創(chuàng)建對(duì)象,都會(huì)先調(diào)用代碼塊的內(nèi)容
//(5) 代碼塊調(diào)用的順序優(yōu)先于構(gòu)造器..
{
System.out.println("電影屏幕打開(kāi)...");
System.out.println("廣告開(kāi)始...");
System.out.println("電影正是開(kāi)始...");
};
public Movie(String name) {
System.out.println("Movie(String name) 被調(diào)用...");
this.name = name;
}
public Movie(String name, double price) {
this.name = name;
this.price = price;
}
public Movie(String name, double price, String director) {
System.out.println("Movie(String name, double price, String director) 被調(diào)用...");
this.name = name;
this.price = price;
this.director = director;
}
}2.2 靜態(tài)代碼塊 & 類(lèi)加載時(shí)機(jī)???
細(xì)節(jié)1
1)?static代碼塊也叫靜態(tài)代碼塊,作用就是對(duì)類(lèi)進(jìn)行初始化,而且它隨著類(lèi)的加載而執(zhí)行,并且只會(huì)執(zhí)行一次。如果是普通代碼塊,每創(chuàng)建一個(gè)對(duì)象,就執(zhí)行。
細(xì)節(jié)2
2)?類(lèi)什么時(shí)候被加載
- 創(chuàng)建對(duì)象實(shí)例時(shí)(new);
- 創(chuàng)建子類(lèi)對(duì)象實(shí)例,父類(lèi)也會(huì)被加載;
- 使用類(lèi)的靜態(tài)成員時(shí)(靜態(tài)屬性,靜態(tài)方法);
案例1:
//1. 創(chuàng)建對(duì)象實(shí)例時(shí)(new)
AA aa = new AA();
class AA {
//靜態(tài)代碼塊
static {
System.out.println("AA 的靜態(tài)代碼1被執(zhí)行...");
}
}AA 的靜態(tài)代碼1被執(zhí)行...
案例2:
//2. 創(chuàng)建子類(lèi)對(duì)象實(shí)例,父類(lèi)也會(huì)被加載, 而且,父類(lèi)先被加載,子類(lèi)后被加載
AA aa2 = new AA();
class BB {
//靜態(tài)代碼塊
static {
System.out.println("BB 的靜態(tài)代碼1被執(zhí)行...");//1
}
}
class AA extends BB {
//靜態(tài)代碼塊
static {
System.out.println("AA 的靜態(tài)代碼1被執(zhí)行...");//2
}
}BB 的靜態(tài)代碼1被執(zhí)行...
AA 的靜態(tài)代碼1被執(zhí)行...
案例3:
//3. 使用類(lèi)的靜態(tài)成員時(shí)(靜態(tài)屬性,靜態(tài)方法)
System.out.println(Cat.n1);
class Animal {
//靜態(tài)代碼塊
static {
System.out.println("Animal 的靜態(tài)代碼1被執(zhí)行...");//1
}
}
class Cat extends Animal {
public static int n1 = 999;//靜態(tài)屬性 3
//靜態(tài)代碼塊
static {
System.out.println("Cat 的靜態(tài)代碼1被執(zhí)行...");//2
}
}Animal 的靜態(tài)代碼1被執(zhí)行...
Cat 的靜態(tài)代碼1被執(zhí)行...
999
細(xì)節(jié)3
3)普通的代碼塊,在創(chuàng)建對(duì)象實(shí)例時(shí),會(huì)被隱式的調(diào)用,被創(chuàng)建一次,就會(huì)調(diào)用一次。
如果只是使用類(lèi)的靜態(tài)成員時(shí),普通代碼塊并不會(huì)執(zhí)行。
小結(jié):
- 1、static代碼塊是類(lèi)加載時(shí),執(zhí)行,只會(huì)執(zhí)行一次;
- 2、普通代碼塊是在創(chuàng)建對(duì)象時(shí)調(diào)用的,創(chuàng)建一次,調(diào)用一次。
細(xì)節(jié)4
4)創(chuàng)建一個(gè)對(duì)象時(shí),在一個(gè)類(lèi)調(diào)用順序時(shí):??
- 調(diào)用靜態(tài)代碼塊和靜態(tài)屬性初始化(注意:靜態(tài)代碼塊和靜態(tài)屬性初始化調(diào)用的優(yōu)先級(jí)一樣,如果有多個(gè)靜態(tài)代碼塊和多個(gè)靜態(tài)變量初始化,則按他們定義的順序調(diào)用);
- 調(diào)用普通代碼塊和普通屬性的初始化(注意:普通代碼塊和普通屬性初始化調(diào)用的優(yōu)先級(jí)一樣,如果有多個(gè)普通代碼塊和多個(gè)普通屬性初始化,則按定義順序調(diào)用);
- 調(diào)用構(gòu)造方法(即構(gòu)造器)。
典型案例:
A a = new A();
class A {
{ //普通代碼塊
System.out.println("A 普通代碼塊01");
}
private int n2 = getN2();//普通屬性的初始化
static { //靜態(tài)代碼塊
System.out.println("A 靜態(tài)代碼塊01");
}
//靜態(tài)屬性的初始化
private static int n1 = getN1();
public static int getN1() {
System.out.println("getN1被調(diào)用...");
return 100;
}
public int getN2() { //普通方法/非靜態(tài)方法
System.out.println("getN2被調(diào)用...");
return 200;
}
//無(wú)參構(gòu)造器
public A() {
System.out.println("A() 構(gòu)造器被調(diào)用");
}
}A 靜態(tài)代碼塊01
getN1被調(diào)用...
A 普通代碼塊01
getN2被調(diào)用...
A() 構(gòu)造器被調(diào)用
細(xì)節(jié)5
5)構(gòu)造器的最前面其實(shí)隱含了super()和調(diào)用普通代碼塊,靜態(tài)相關(guān)的代碼塊,屬性初始化,在類(lèi)加載時(shí),就執(zhí)行完畢,因此是優(yōu)先于構(gòu)造器和普通代碼塊執(zhí)行的。
案例:
new BBB();
class AAA { //父類(lèi)Object
{
System.out.println("AAA的普通代碼塊");
}
public AAA() {
//(1)super()
//(2)調(diào)用本類(lèi)的普通代碼塊
System.out.println("AAA() 構(gòu)造器被調(diào)用....");
}
}
class BBB extends AAA {
{
System.out.println("BBB的普通代碼塊...");
}
public BBB() {
//(1)super()
//(2)調(diào)用本類(lèi)的普通代碼塊
System.out.println("BBB() 構(gòu)造器被調(diào)用....");
}
}AAA的普通代碼塊
AAA() 構(gòu)造器被調(diào)用....
BBB的普通代碼塊...
BBB() 構(gòu)造器被調(diào)用....
細(xì)節(jié)6
6)創(chuàng)建含繼承關(guān)系的一個(gè)子類(lèi)對(duì)象時(shí),他們的靜態(tài)代碼塊,靜態(tài)屬性初始化,普通代碼塊,普通屬性初始化,構(gòu)造方法的調(diào)用順序如下:???
- 父類(lèi)的靜態(tài)代碼塊和靜態(tài)屬性(優(yōu)先級(jí)一樣,按定義順序執(zhí)行);
- 子類(lèi)的靜態(tài)代碼塊和靜態(tài)屬性(優(yōu)先級(jí)一樣,按定義順序執(zhí)行);
- 父類(lèi)的普通代碼塊和普通屬性初始化(優(yōu)先級(jí)一樣,按定義順序執(zhí)行);
- 父類(lèi)的構(gòu)造方法(構(gòu)造器);
- 子類(lèi)的普通代碼塊和普通屬性初始化(優(yōu)先級(jí)一樣,按定義順序執(zhí)行;
- 子類(lèi)的構(gòu)造方法(構(gòu)造器)。
經(jīng)典案例:
new B02();
class A02 { //父類(lèi)
private static int n1 = getVal01();
static {
System.out.println("A02的一個(gè)靜態(tài)代碼塊..");//(2)
}
{
System.out.println("A02的第一個(gè)普通代碼塊..");//(5)
}
public int n3 = getVal02();//普通屬性的初始化
public static int getVal01() {
System.out.println("getVal01");//(1)
return 10;
}
public int getVal02() {
System.out.println("getVal02");//(6)
return 10;
}
public A02() {//構(gòu)造器
//隱藏
//super()
//普通代碼和普通屬性的初始化......
System.out.println("A02的構(gòu)造器");//(7)
}
}
class B02 extends A02 { //
private static int n3 = getVal03();
static {
System.out.println("B02的一個(gè)靜態(tài)代碼塊..");//(4)
}
public int n5 = getVal04();
{
System.out.println("B02的第一個(gè)普通代碼塊..");//(9)
}
public static int getVal03() {
System.out.println("getVal03");//(3)
return 10;
}
public int getVal04() {
System.out.println("getVal04");//(8)
return 10;
}
//一定要慢慢的去品..
public B02() {//構(gòu)造器
//隱藏了
//super()
//普通代碼塊和普通屬性的初始化...
System.out.println("B02的構(gòu)造器");//(10)
}
}細(xì)節(jié)7
7)靜態(tài)代碼塊只能直接調(diào)用靜態(tài)成員(靜態(tài)屬性和靜態(tài)方法),普通代碼塊可以調(diào)用任意成員。
經(jīng)典案例:
class C02 {
private int n1 = 100;
private static int n2 = 200;
private void m1() {}
private static void m2() {}
static {
//靜態(tài)代碼塊,只能調(diào)用靜態(tài)成員
//System.out.println(n1);錯(cuò)誤
System.out.println(n2);//ok
//m1();//錯(cuò)誤
m2();
}
{
//普通代碼塊,可以使用任意成員
System.out.println(n1);
System.out.println(n2);//ok
m1();
m2();
}
}200
100
200
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java中servlet實(shí)現(xiàn)登錄驗(yàn)證的方法
做web開(kāi)發(fā),登錄驗(yàn)證是免不了的,今天學(xué)習(xí)了servlet的登錄驗(yàn)證,當(dāng)然是很簡(jiǎn)單的,沒(méi)有使用session,request等作用域?qū)ο?,所以還是可以直接通過(guò)地址訪(fǎng)問(wèn)網(wǎng)頁(yè)的。2013-05-05
jmeter接口測(cè)試教程及接口測(cè)試流程詳解(全網(wǎng)僅有)
Jmeter是由Apache公司開(kāi)發(fā)的一個(gè)純Java的開(kāi)源項(xiàng)目,即可以用于做接口測(cè)試也可以用于做性能測(cè)試。本文給大家分享jmeter接口測(cè)試教程及接口測(cè)試流程,感興趣的朋友跟隨小編一起看看吧2021-12-12
Java中AuthorizationFilter過(guò)濾器的功能
本文主要介紹了Java中AuthorizationFilter過(guò)濾器的功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2026-02-02
java并發(fā)中ExecutorService的具體用法
本文深入探討Java中的ExecutorService框架,介紹其創(chuàng)建方法、任務(wù)分配、關(guān)閉策略及Future、ScheduledExecutorService的使用,對(duì)比Fork/Join框架,提供豐富的代碼示例,感興趣的朋友跟隨小編一起看看吧2025-09-09
Spring如何解決接口多實(shí)現(xiàn)類(lèi)的依賴(lài)注入沖突
在 Spring 中,當(dāng)一個(gè)接口有多個(gè)實(shí)現(xiàn)類(lèi)時(shí),依賴(lài)注入(DI)的歧義性問(wèn)題是一個(gè)常見(jiàn)挑戰(zhàn),本文為大家介紹了如何根據(jù)場(chǎng)景選擇最優(yōu)方案,希望對(duì)大家有所幫助2025-08-08
Java 8函數(shù)式接口Function BiFunction DoubleFunction
這篇文章主要為大家介紹了Java 8函數(shù)式接口Function BiFunction DoubleFunction區(qū)別示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
Java后端向前端返回文件流實(shí)現(xiàn)下載功能
后端可以使用Java中servlet提供的HttpServletResponse,核心步驟是要設(shè)置響應(yīng)的數(shù)據(jù)類(lèi)型,設(shè)置為某一類(lèi)文件類(lèi)型或二進(jìn)制格式,以及響應(yīng)頭,然后用ServletOutputStream將文件以流的形式發(fā)送到前端,本文介紹Java后端向前端返回文件流實(shí)現(xiàn)下載功能,感興趣的朋友一起看看吧2023-12-12

