Java構(gòu)造器之從基礎(chǔ)特征到權(quán)限修飾符
在Java面向?qū)ο缶幊讨?,?gòu)造器(也叫構(gòu)造方法)是貫穿“對(duì)象創(chuàng)建與初始化”的核心知識(shí)點(diǎn)——它是對(duì)象誕生時(shí)的“初始化工具”,負(fù)責(zé)給對(duì)象分配內(nèi)存、設(shè)置初始數(shù)據(jù),也是新手容易混淆“普通方法”的高頻難點(diǎn)。
很多初學(xué)者會(huì)把構(gòu)造器和普通方法搞混,比如“為什么構(gòu)造器沒(méi)有返回值?”“默認(rèn)無(wú)參構(gòu)造器什么時(shí)候存在?”“權(quán)限修飾符對(duì)構(gòu)造器有什么影響?”,今天這篇博客,將結(jié)合權(quán)限修飾符詳解、實(shí)戰(zhàn)代碼案例,逐一拆解構(gòu)造器的核心特征、隱藏規(guī)則和易錯(cuò)點(diǎn),從基礎(chǔ)到細(xì)節(jié),讓新手也能徹底吃透構(gòu)造器,同時(shí)適配面試高頻考點(diǎn),干貨無(wú)冗余。
一、先理清:構(gòu)造器是什么?和普通方法有何不同?
Java中的構(gòu)造方法(Constructor)是一種特殊的方法,核心作用只有一個(gè):初始化對(duì)象。當(dāng)我們使用new關(guān)鍵字創(chuàng)建對(duì)象時(shí),JVM會(huì)自動(dòng)調(diào)用構(gòu)造器,在對(duì)象被創(chuàng)建的瞬間,完成對(duì)象的數(shù)據(jù)初始化(比如給成員變量賦值、分配內(nèi)存資源)。
構(gòu)造器與普通方法的核心區(qū)別(一句話分清)
- 普通方法:用于實(shí)現(xiàn)特定功能(如get/set方法、業(yè)務(wù)邏輯方法),需要手動(dòng)調(diào)用,有返回值(void也算返回值類(lèi)型); - 構(gòu)造器:用于初始化對(duì)象,無(wú)需手動(dòng)調(diào)用,JVM在new對(duì)象時(shí)自動(dòng)調(diào)用,沒(méi)有返回值(連void都不能寫(xiě)),且方法名必須與類(lèi)名完全一致。
二、鋪墊:Java訪問(wèn)權(quán)限修飾符(構(gòu)造器必用)
構(gòu)造器和普通方法一樣,也可以使用訪問(wèn)權(quán)限修飾符(public、protected、默認(rèn)、private),控制構(gòu)造器的訪問(wèn)范圍(比如能否在其他類(lèi)、其他包中創(chuàng)建當(dāng)前類(lèi)的對(duì)象)。在講解構(gòu)造器特征前,先吃透Java4種訪問(wèn)權(quán)限修飾符的作用,后續(xù)理解構(gòu)造器的訪問(wèn)控制會(huì)更輕松。
Java訪問(wèn)權(quán)限修飾符明細(xì)表(清晰易懂)
訪問(wèn)權(quán)限修飾符 | 當(dāng)前類(lèi) | 同包下的類(lèi) | 不同包下的子類(lèi) | 其他包下的非子類(lèi) |
|---|---|---|---|---|
public(公共) | √ 可訪問(wèn) | √ 可訪問(wèn) | √ 可訪問(wèn) | √ 可訪問(wèn) |
protected(受保護(hù)) | √ 可訪問(wèn) | √ 可訪問(wèn) | √ 可訪問(wèn) | × 不可訪問(wèn) |
默認(rèn)(無(wú)修飾符) | √ 可訪問(wèn) | √ 可訪問(wèn) | × 不可訪問(wèn) | × 不可訪問(wèn) |
private(私有) | √ 可訪問(wèn) | × 不可訪問(wèn) | × 不可訪問(wèn) | × 不可訪問(wèn) |
關(guān)鍵區(qū)別:protected vs 默認(rèn)修飾符(新手必記)
很多新手會(huì)混淆protected和默認(rèn)修飾符的作用,兩者的核心區(qū)別的是: 默認(rèn)修飾符(無(wú)修飾符):僅限制在當(dāng)前包內(nèi)訪問(wèn),哪怕是其他包下的子類(lèi),也無(wú)法訪問(wèn)(包括無(wú)法調(diào)用默認(rèn)修飾的構(gòu)造器、方法); protected修飾符:除了當(dāng)前類(lèi)、同包類(lèi)可訪問(wèn),其他包下的子類(lèi)也能訪問(wèn)——這是兩者最核心的差異,也是構(gòu)造器訪問(wèn)控制中容易踩坑的點(diǎn)。
舉例:如果一個(gè)類(lèi)的構(gòu)造器用默認(rèn)修飾符,那么其他包下的子類(lèi)無(wú)法通過(guò)new關(guān)鍵字創(chuàng)建該類(lèi)的對(duì)象;但如果構(gòu)造器用protected修飾,其他包下的子類(lèi)就能創(chuàng)建對(duì)象。
三、核心重點(diǎn):Java構(gòu)造器的5大特征(必記+實(shí)戰(zhàn)演示)
構(gòu)造器的特征是面試高頻考點(diǎn),也是使用構(gòu)造器的核心準(zhǔn)則,每一個(gè)特征都結(jié)合實(shí)戰(zhàn)代碼演示,讓大家不僅能記住,還能靈活運(yùn)用。
特征1:構(gòu)造器的方法名,必須與類(lèi)名完全一致(大小寫(xiě)也必須一致)
這是構(gòu)造器最直觀的特征,也是區(qū)分構(gòu)造器和普通方法的關(guān)鍵之一——只要方法名和類(lèi)名不一致,哪怕其他特征都符合,也不是構(gòu)造器(而是普通方法)。
/**
* 實(shí)戰(zhàn)案例:Student類(lèi)(演示構(gòu)造器命名規(guī)則)
*/
public class Student {
// 成員變量(需要被初始化)
private String name;
private int age;
private char sex;
private int sno; // 學(xué)號(hào)
// 正確的構(gòu)造器:方法名與類(lèi)名(Student)完全一致
public Student(String name, int age, char sex, int sno) {
// this關(guān)鍵字:區(qū)分成員變量和局部變量,給成員變量賦值
this.name = name;
this.age = age;
this.sex = sex;
this.sno = sno;
}
// 錯(cuò)誤示例:方法名與類(lèi)名不一致(student小寫(xiě)),不是構(gòu)造器,是普通方法
public void student(String name) {
this.name = name;
}
}注意:Java是大小寫(xiě)敏感的語(yǔ)言,比如類(lèi)名是Student(首字母大寫(xiě)),構(gòu)造器名寫(xiě)成student(首字母小寫(xiě)),就不是構(gòu)造器,只是一個(gè)普通的void方法(默認(rèn)返回值void,可省略)。
特征2:構(gòu)造器在對(duì)象創(chuàng)建時(shí)被自動(dòng)調(diào)用,無(wú)需手動(dòng)調(diào)用
構(gòu)造器的調(diào)用時(shí)機(jī)是“對(duì)象創(chuàng)建時(shí)”,也就是使用new關(guān)鍵字的瞬間——new關(guān)鍵字后面的“方法名”,本質(zhì)就是我們要調(diào)用的構(gòu)造器,無(wú)需像普通方法那樣“對(duì)象.方法名()"手動(dòng)調(diào)用。
public class TestStudent {
public static void main(String[] args) {
// 1. 使用new關(guān)鍵字創(chuàng)建Student對(duì)象,此時(shí)JVM自動(dòng)調(diào)用構(gòu)造器
// new后面的Student(...),就是調(diào)用上面定義的有參構(gòu)造器
Student student = new Student("張三", 18, '男', 2024001);
// 2. 構(gòu)造器無(wú)需手動(dòng)調(diào)用,以下寫(xiě)法錯(cuò)誤(構(gòu)造器不能這樣調(diào)用)
// student.Student("李四", 19, '女', 2024002); // 報(bào)錯(cuò)
}
}核心邏輯:new關(guān)鍵字的作用有兩個(gè)——① 給對(duì)象分配內(nèi)存空間;② 調(diào)用構(gòu)造器,完成對(duì)象的初始化。兩者是綁定的,只要有new,就一定會(huì)調(diào)用構(gòu)造器。
特征3:每個(gè)類(lèi)都有默認(rèn)的無(wú)參構(gòu)造器(隱藏規(guī)則,新手必懂)
這是構(gòu)造器最容易被忽略的特征,也是新手最容易踩坑的點(diǎn): 當(dāng)我們沒(méi)有在類(lèi)中顯式定義任何構(gòu)造器時(shí),JVM會(huì)自動(dòng)給這個(gè)類(lèi)添加一個(gè)“默認(rèn)的無(wú)參構(gòu)造器”——這個(gè)構(gòu)造器是隱藏的、無(wú)修飾符(默認(rèn)權(quán)限)、無(wú)參數(shù)、無(wú)方法體,僅用于完成對(duì)象的基礎(chǔ)初始化。
實(shí)戰(zhàn)演示:默認(rèn)無(wú)參構(gòu)造器的隱藏與顯示
/**
* 案例1:未顯式定義任何構(gòu)造器,JVM自動(dòng)添加默認(rèn)無(wú)參構(gòu)造器
*/
public class Teacher {
private String name;
private int age;
// 無(wú)任何顯式構(gòu)造器,JVM自動(dòng)添加默認(rèn)無(wú)參構(gòu)造器(隱藏)
// 隱藏的默認(rèn)無(wú)參構(gòu)造器:
// Teacher() {}
}
// 測(cè)試類(lèi)
public class TestTeacher {
public static void main(String[] args) {
// 可以直接調(diào)用默認(rèn)無(wú)參構(gòu)造器創(chuàng)建對(duì)象(JVM自動(dòng)提供)
Teacher teacher = new Teacher(); // 不報(bào)錯(cuò),正常創(chuàng)建對(duì)象
}
}
/**
* 案例2:顯式定義構(gòu)造器后,默認(rèn)無(wú)參構(gòu)造器會(huì)“消失”
*/
public class Teacher {
private String name;
private int age;
// 顯式定義一個(gè)有參構(gòu)造器
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
// 此時(shí),JVM不再提供默認(rèn)無(wú)參構(gòu)造器(隱藏的無(wú)參構(gòu)造器消失)
}
// 測(cè)試類(lèi)
public class TestTeacher {
public static void main(String[] args) {
// 報(bào)錯(cuò):無(wú)法找到無(wú)參構(gòu)造器(默認(rèn)無(wú)參已消失)
Teacher teacher1 = new Teacher(); // 編譯報(bào)錯(cuò)
// 正確:只能調(diào)用顯式定義的有參構(gòu)造器
Teacher teacher2 = new Teacher("李老師", 30); // 正常創(chuàng)建
}
}易錯(cuò)點(diǎn)提醒
如果我們顯式定義了構(gòu)造器(無(wú)論有參還是無(wú)參),JVM就不會(huì)再提供默認(rèn)的無(wú)參構(gòu)造器;此時(shí)如果需要使用無(wú)參構(gòu)造器創(chuàng)建對(duì)象,必須手動(dòng)顯式定義無(wú)參構(gòu)造器,否則會(huì)編譯報(bào)錯(cuò)。
// 正確寫(xiě)法:顯式定義有參構(gòu)造器+無(wú)參構(gòu)造器
public class Teacher {
private String name;
private int age;
// 手動(dòng)顯式定義無(wú)參構(gòu)造器
public Teacher() {
// 可自定義初始化邏輯,也可空方法體
this.name = "默認(rèn)姓名";
this.age = 0;
}
// 顯式定義有參構(gòu)造器
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
}特征4:構(gòu)造器沒(méi)有返回值(連void都不能寫(xiě))
這是構(gòu)造器與普通方法最核心的區(qū)別之一——普通方法可以有返回值(包括void),但構(gòu)造器絕對(duì)不能有返回值,哪怕是void也不行。
如果一個(gè)方法的名字和類(lèi)名相同,但有返回值(包括void),那么它就不是構(gòu)造器,只是一個(gè)普通方法,無(wú)法被JVM在new對(duì)象時(shí)自動(dòng)調(diào)用。
public class Student {
private String name;
// 正確的構(gòu)造器:無(wú)返回值(無(wú)void,無(wú)其他返回類(lèi)型)
public Student(String name) {
this.name = name;
}
// 錯(cuò)誤示例1:有返回值String,不是構(gòu)造器(普通方法)
public String Student() {
return this.name;
}
// 錯(cuò)誤示例2:有返回值void,不是構(gòu)造器(普通方法)
public void Student() {
this.name = "默認(rèn)姓名";
}
}注意:構(gòu)造器的“無(wú)返回值”,不是指“返回值為void”,而是“根本沒(méi)有返回值聲明”——void是一種返回值類(lèi)型(表示無(wú)返回值),但構(gòu)造器不能聲明任何返回值類(lèi)型,包括void。
特征5:一個(gè)類(lèi)中可以有1個(gè)或多個(gè)構(gòu)造器(構(gòu)造器重載)
Java支持構(gòu)造器重載,也就是說(shuō),一個(gè)類(lèi)中可以定義多個(gè)構(gòu)造器,只要它們的參數(shù)列表不同(參數(shù)個(gè)數(shù)不同、參數(shù)類(lèi)型不同、參數(shù)順序不同),就可以共存——這樣我們就可以根據(jù)不同的需求,通過(guò)不同的構(gòu)造器創(chuàng)建對(duì)象(實(shí)現(xiàn)不同的初始化邏輯)。
/**
* 實(shí)戰(zhàn)案例:構(gòu)造器重載(多個(gè)構(gòu)造器共存)
*/
public class Student {
private String name;
private int age;
private char sex;
private int sno;
// 構(gòu)造器1:無(wú)參構(gòu)造器(手動(dòng)定義)
public Student() {
this.name = "默認(rèn)姓名";
this.age = 0;
this.sex = '未知';
this.sno = 0;
}
// 構(gòu)造器2:1個(gè)參數(shù)(僅初始化姓名)
public Student(String name) {
this.name = name;
this.age = 0;
this.sex = '未知';
this.sno = 0;
}
// 構(gòu)造器3:2個(gè)參數(shù)(初始化姓名、年齡)
public Student(String name, int age) {
this.name = name;
this.age = age;
this.sex = '未知';
this.sno = 0;
}
// 構(gòu)造器4:4個(gè)參數(shù)(初始化所有成員變量)
public Student(String name, int age, char sex, int sno) {
this.name = name;
this.age = age;
this.sex = sex;
this.sno = sno;
}
}測(cè)試類(lèi)調(diào)用不同構(gòu)造器:
public class TestStudent {
public static void main(String[] args) {
// 調(diào)用無(wú)參構(gòu)造器
Student s1 = new Student();
// 調(diào)用1個(gè)參數(shù)的構(gòu)造器
Student s2 = new Student("張三");
// 調(diào)用2個(gè)參數(shù)的構(gòu)造器
Student s3 = new Student("李四", 18);
// 調(diào)用4個(gè)參數(shù)的構(gòu)造器
Student s4 = new Student("王五", 19, '男', 2024002);
}
}構(gòu)造器重載的核心:參數(shù)列表不同,與訪問(wèn)權(quán)限修飾符、返回值(構(gòu)造器無(wú)返回值)無(wú)關(guān);通過(guò)構(gòu)造器重載,我們可以靈活控制對(duì)象的初始化方式,滿足不同的業(yè)務(wù)需求。
四、高頻易錯(cuò)點(diǎn)總結(jié)(面試必避坑)
結(jié)合前面的知識(shí)點(diǎn),整理5個(gè)新手最容易踩的構(gòu)造器易錯(cuò)點(diǎn),也是面試高頻考點(diǎn),記牢這些,避免寫(xiě)代碼報(bào)錯(cuò)、面試翻車(chē)。
- 顯式定義構(gòu)造器后,默認(rèn)無(wú)參構(gòu)造器會(huì)消失,如需使用無(wú)參創(chuàng)建對(duì)象,必須手動(dòng)定義;
- 構(gòu)造器沒(méi)有返回值,連void都不能寫(xiě),否則就是普通方法,無(wú)法被JVM自動(dòng)調(diào)用;
- 構(gòu)造器名必須與類(lèi)名完全一致(大小寫(xiě)一致),否則不是構(gòu)造器;
- 默認(rèn)修飾符與protected的區(qū)別:默認(rèn)修飾的構(gòu)造器,其他包下的子類(lèi)無(wú)法訪問(wèn);protected修飾的構(gòu)造器,其他包下的子類(lèi)可以訪問(wèn);
- 構(gòu)造器重載的關(guān)鍵是“參數(shù)列表不同”,與訪問(wèn)權(quán)限、返回值無(wú)關(guān)(構(gòu)造器無(wú)返回值)。
五、全文核心總結(jié)
Java構(gòu)造器是對(duì)象初始化的核心工具,本質(zhì)是一種特殊的方法,核心作用是在new對(duì)象時(shí),完成對(duì)象的內(nèi)存分配和數(shù)據(jù)初始化;
掌握構(gòu)造器的5大特征,理解訪問(wèn)權(quán)限修飾符的作用,分清構(gòu)造器與普通方法的區(qū)別,避開(kāi)常見(jiàn)易錯(cuò)點(diǎn),就能靈活運(yùn)用構(gòu)造器;
實(shí)際開(kāi)發(fā)中,構(gòu)造器重載是高頻用法,結(jié)合訪問(wèn)權(quán)限修飾符,可控制對(duì)象的創(chuàng)建范圍(比如private構(gòu)造器可實(shí)現(xiàn)單例模式),后續(xù)會(huì)講解構(gòu)造器的進(jìn)階用法(如構(gòu)造器調(diào)用構(gòu)造器、單例模式)。
到此這篇關(guān)于Java構(gòu)造器之從基礎(chǔ)特征到權(quán)限修飾符的文章就介紹到這了,更多相關(guān)java構(gòu)造器權(quán)限修飾符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Swing組件實(shí)現(xiàn)進(jìn)度監(jiān)視功能示例
這篇文章主要介紹了Java Swing組件實(shí)現(xiàn)進(jìn)度監(jiān)視功能,結(jié)合完整實(shí)例形式詳細(xì)分析了Java基于Swing組件實(shí)現(xiàn)進(jìn)度條顯示功能的具體操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下2018-02-02
利用Java查看進(jìn)程內(nèi)存占用情況的實(shí)現(xiàn)方法
在系統(tǒng)監(jiān)控和性能調(diào)優(yōu)中,了解各個(gè)進(jìn)程的內(nèi)存占用情況是非常重要的一環(huán),通過(guò)查看進(jìn)程內(nèi)存使用情況,開(kāi)發(fā)者和運(yùn)維人員可以及時(shí)發(fā)現(xiàn)異常進(jìn)程、資源瓶頸和內(nèi)存泄漏問(wèn)題,本項(xiàng)目旨在使用 Java 編寫(xiě)一個(gè)簡(jiǎn)單的程序,通過(guò)調(diào)用操作系統(tǒng)的命令來(lái)獲取系統(tǒng)中各個(gè)進(jìn)程的內(nèi)存使用情況2025-03-03
解決mybatis-plus自動(dòng)配置的mapper.xml與java接口映射問(wèn)題
這篇文章主要介紹了解決mybatis-plus自動(dòng)配置的mapper.xml與java接口映射問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Spring集成Druid連接池及監(jiān)控配置的全過(guò)程
java程序很大一部分要操作數(shù)據(jù)庫(kù),為了提高性能操作數(shù)據(jù)庫(kù)的時(shí)候,有不得不使用數(shù)據(jù)庫(kù)連接池,下面這篇文章主要給大家介紹了關(guān)于Spring集成Druid連接池及監(jiān)控配置的相關(guān)資料,需要的朋友可以參考下2021-09-09
java中的編碼轉(zhuǎn)換過(guò)程(以u(píng)tf8和gbk為例)
這篇文章主要介紹了java中的編碼轉(zhuǎn)換過(guò)程(以u(píng)tf8和gbk為例),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
JpaRepository如何實(shí)現(xiàn)增刪改查并進(jìn)行單元測(cè)試
這篇文章主要介紹了JpaRepository如何實(shí)現(xiàn)增刪改查并進(jìn)行單元測(cè)試,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11
Java SpringBoot的相關(guān)知識(shí)點(diǎn)詳解
這篇文章主要介紹了SpringBoot的相關(guān)知識(shí)點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-10-10

