目 Java 訪問(wèn)修飾符 + 非訪問(wèn)修飾符全景梳理詳解)
前言Java 修飾符分為兩大體系訪問(wèn)權(quán)限修飾符控制類(lèi) / 成員可見(jiàn)范圍、非訪問(wèn)修飾符定義特性、生命周期、Spring 框架專(zhuān)屬語(yǔ)義。 SpringBoot/Spring 開(kāi)發(fā)中修飾符貫穿 Controller、Service、Mapper、實(shí)體類(lèi)、工具類(lèi)、配置類(lèi)全場(chǎng)景不同修飾符搭配注解會(huì)產(chǎn)生截然不同的 Bean 生命周期、依賴(lài)注入、序列化、繼承效果。 本文以多表格拆分 場(chǎng)景適配 Spring 工程實(shí)操規(guī)范完整梳理。一、第一大類(lèi)訪問(wèn)權(quán)限修飾符4 個(gè)控制可見(jiàn)范圍核心作用限定類(lèi)、成員變量、成員方法、構(gòu)造器可被調(diào)用的范圍作用域從小到大排序private 默認(rèn)(包私有) protected public表 1四大訪問(wèn)修飾符作用域?qū)φ毡硇揎椃形拿Q(chēng)本類(lèi)內(nèi)部同一個(gè)包下其他類(lèi)子類(lèi)不同包任意包所有類(lèi)Spring 項(xiàng)目常規(guī)使用場(chǎng)景private私有? 可見(jiàn)? 不可見(jiàn)? 不可見(jiàn)? 不可見(jiàn)1.Service 注入的 Mapper 成員變量 2. 實(shí)體類(lèi) PO/DO 所有屬性字段 3. 工具類(lèi)內(nèi)部私有工具方法 4. 常量私有成員無(wú)修飾符 default包私有 / 默認(rèn)? 可見(jiàn)? 可見(jiàn)? 不可見(jiàn)? 不可見(jiàn)Spring 極少主動(dòng)使用僅同一包內(nèi)協(xié)作工具類(lèi)臨時(shí)方法protected受保護(hù)? 可見(jiàn)? 可見(jiàn)? 可見(jiàn)? 不可見(jiàn)1. 父類(lèi)公共基礎(chǔ) PO 審計(jì)字段createTime/updateTime 2. 抽象父 Service 通用業(yè)務(wù)模板方法public公共? 可見(jiàn)? 可見(jiàn)? 可見(jiàn)? 可見(jiàn)1.Controller 所有接口方法 2.Service 接口定義、實(shí)現(xiàn)類(lèi)對(duì)外業(yè)務(wù)方法 3.Mapper 接口 4. 對(duì)外暴露的工具類(lèi)靜態(tài)方法表 2訪問(wèn)修飾符使用硬性規(guī)范Spring 工程最佳實(shí)踐代碼元素推薦修飾符禁止使用原因說(shuō)明實(shí)體類(lèi) PO/DTO/Form 屬性字段privatepublic封裝特性通過(guò) get/set 訪問(wèn)Jackson 序列化默認(rèn)適配私有字段Service 層注入 Mapper 對(duì)象privatepublic/protected依賴(lài)注入無(wú)需對(duì)外暴露保證封裝Controller 接口請(qǐng)求方法public其他SpringMVC 需要外部反射調(diào)用接口方法必須 public業(yè)務(wù)接口XXXServicepublicdefault跨包調(diào)用實(shí)現(xiàn)類(lèi)必須公共工具類(lèi)內(nèi)部工具方法privatepublic僅類(lèi)內(nèi)調(diào)用無(wú)需對(duì)外開(kāi)放抽象父類(lèi)模板方法protectedprivate供子類(lèi)重寫(xiě)拓展外部不可調(diào)用二、第二大類(lèi)基礎(chǔ)非訪問(wèn)修飾符Java 原生核心修飾符Spring 高頻搭配注解使用模塊 1static 靜態(tài)修飾符表 3static 修飾不同元素效果 Spring 場(chǎng)景修飾對(duì)象核心特性Spring 開(kāi)發(fā)適用場(chǎng)景禁忌場(chǎng)景static 變量靜態(tài)變量屬于類(lèi)本身不屬于實(shí)例全局唯一一份內(nèi)存所有對(duì)象共享1. 全局常量public static final 2. 工具類(lèi)全局配置參數(shù)不能修飾 Autowired 注入成員靜態(tài)變量無(wú)法被 Spring 自動(dòng)注入static 方法靜態(tài)方法無(wú)需 new 實(shí)例類(lèi)名。方法名 () 直接調(diào)用內(nèi)部只能訪問(wèn)靜態(tài)資源通用工具類(lèi)日期轉(zhuǎn)換、Bean 拷貝、加解密工具方法不能調(diào)用非靜態(tài)成員不能加 Transactional 事務(wù)注解事務(wù)依賴(lài)實(shí)例代理static 代碼塊類(lèi)加載時(shí)執(zhí)行一次僅初始化靜態(tài)資源工具類(lèi)加載初始化配置、加載證書(shū)文件業(yè)務(wù)層幾乎不用static 內(nèi)部類(lèi)脫離外部類(lèi)可獨(dú)立實(shí)例化復(fù)雜 DTO 嵌套內(nèi)部枚舉 / 子對(duì)象極少使用模塊 2final 最終修飾符不可修改表 4final 修飾不同元素規(guī)則對(duì)照表修飾對(duì)象語(yǔ)義約束Spring 項(xiàng)目使用場(chǎng)景final 變量賦值一次后永久不可修改1. 全局常量public static final String REDIS_PREFIX user:;2. 方法入?yún)⒔狗椒▋?nèi)篡改入?yún)?duì)象引用final 方法子類(lèi)無(wú)法重寫(xiě)該方法父類(lèi)固定模板方法不允許子類(lèi)篡改核心邏輯final 類(lèi)類(lèi)不能被繼承無(wú)子類(lèi)1. 通用工具類(lèi)BeanUtil、DateUtil 2. 枚舉類(lèi)默認(rèn)都是 final模塊 3abstract 抽象修飾符面向接口編程核心Spring 架構(gòu)基石表 5abstract 使用規(guī)則 業(yè)務(wù)場(chǎng)景修飾對(duì)象約束規(guī)則Spring 架構(gòu)場(chǎng)景abstract 抽象類(lèi)不能 new 實(shí)例可包含抽象方法 普通成員變量 / 普通方法通用父 BaseService、BaseController封裝分頁(yè)、異常統(tǒng)一處理abstract 抽象方法無(wú)方法體必須被子類(lèi)實(shí)現(xiàn)重寫(xiě)模板方法模式定義業(yè)務(wù)標(biāo)準(zhǔn)流程子類(lèi)差異化實(shí)現(xiàn)關(guān)鍵接口 interface 默認(rèn)所有方法都是 public abstract模塊 4synchronized /volatile/transient 并發(fā)序列化修飾符表 6并發(fā) 序列化修飾符場(chǎng)景明細(xì)修飾符核心作用Spring 使用場(chǎng)景synchronized同步鎖保證多線程原子性、可見(jiàn)性定時(shí)任務(wù)多線程并發(fā)爭(zhēng)搶資源、庫(kù)存扣減簡(jiǎn)易加鎖分布式推薦 Redissonvolatile保證變量?jī)?nèi)存可見(jiàn)性禁止指令重排多線程全局開(kāi)關(guān)標(biāo)記定時(shí)任務(wù)啟停標(biāo)記transient序列化忽略字段PO 實(shí)體中不需要存入 Redis / 序列化的臨時(shí)字段三、第三大類(lèi)Spring 生態(tài)專(zhuān)屬語(yǔ)義修飾結(jié)合注解生效Java 原生修飾符 Spring 注解聯(lián)動(dòng)Spring 不會(huì)新增語(yǔ)法修飾符但通過(guò)原生修飾符 框架注解賦予特殊生命周期、依賴(lài)注入、代理特性是業(yè)務(wù)開(kāi)發(fā)最常用組合。表 7Autowired 注入場(chǎng)景修飾符搭配規(guī)范成員變量修飾符搭配 Autowired 效果推薦度privateSpring 反射無(wú)視私有權(quán)限可正常注入封裝性最好????? 標(biāo)準(zhǔn)寫(xiě)法protected子類(lèi)可直接訪問(wèn)注入對(duì)象適合父子 Service 繼承場(chǎng)景????public外部可隨意修改注入 Bean破壞容器單例不推薦?final搭配構(gòu)造注入推薦寫(xiě)法private final UserMapper userMapper;構(gòu)造器注入不可變 Bean????? Spring 官方推薦表 8Bean 作用域 修飾符聯(lián)動(dòng)單例 / 多例修飾符組合Bean 生命周期特性使用場(chǎng)景private static Autowired禁止使用靜態(tài)變量只會(huì)注入一次單例容器下會(huì)出現(xiàn)注入失效? 嚴(yán)禁private final 構(gòu)造注入Bean 創(chuàng)建完成后無(wú)法被修改線程安全無(wú)循環(huán)依賴(lài)隱患? 生產(chǎn)首選四、第四大類(lèi)方法專(zhuān)屬修飾符匯總接口 / 實(shí)現(xiàn)類(lèi)方法全覆蓋表 9方法所有修飾符組合含義對(duì)照表修飾符組合適用位置核心作用public voidController 接口方法接收前端 http 請(qǐng)求SpringMVC 反射調(diào)用public OverrideService 實(shí)現(xiàn)類(lèi)重寫(xiě)接口方法實(shí)現(xiàn)業(yè)務(wù)規(guī)范編譯器校驗(yàn)方法簽名protected abstract抽象父類(lèi)模板方法預(yù)留拓展點(diǎn)子類(lèi)必須實(shí)現(xiàn)private static工具類(lèi)內(nèi)部靜態(tài)工具方法全局調(diào)用無(wú)狀態(tài)線程安全public static final常量工具方法邏輯永久固定不可重寫(xiě)private synchronized類(lèi)內(nèi)多線程同步方法本地鎖保證線程安全五、綜合總表Spring 分層代碼全層級(jí)修飾符標(biāo)準(zhǔn)配置表 10項(xiàng)目各層代碼統(tǒng)一修飾符規(guī)范企業(yè)級(jí)開(kāi)發(fā)標(biāo)準(zhǔn)代碼分層代碼元素標(biāo)準(zhǔn)修飾符補(bǔ)充說(shuō)明控制層 Controller類(lèi)public交給 SpringMVC 掃描注冊(cè) Bean請(qǐng)求接口方法public必須公共才能被外部訪問(wèn)業(yè)務(wù)層 Service業(yè)務(wù)接口public跨包調(diào)用接口實(shí)現(xiàn)類(lèi)ServicepublicIOC 容器托管注入 Mapper 成員變量private final構(gòu)造器注入官方最優(yōu)方案業(yè)務(wù)實(shí)現(xiàn)方法public供上層調(diào)用數(shù)據(jù)訪問(wèn)層 MapperMapper 接口publicMyBatis 掃描生成代理對(duì)象實(shí)體層 PO/DTO/Form實(shí)體類(lèi)public序列化反射需要所有屬性字段private封裝get/set 訪問(wèn)get/set 方法publicJackson 序列化依賴(lài)公共 getter通用工具類(lèi)工具類(lèi)public final禁止繼承工具方法public static類(lèi)名直接調(diào)用全局常量public static final統(tǒng)一配置常量配置類(lèi) Configuration配置類(lèi)publicSpring 掃描配置 BeanBean 生成對(duì)象方法public容器注冊(cè)第三方組件六、高頻易錯(cuò)坑點(diǎn)總結(jié)? 靜態(tài)變量不能使用 Autowiredstatic 屬于類(lèi)加載階段早于 Spring 容器初始化注入一定會(huì)失效? private 方法不能加 TransactionalSpring 事務(wù)基于 JDK/CGLIB 動(dòng)態(tài)代理私有方法無(wú)法被代理攔截事務(wù)不生效? final 成員變量推薦構(gòu)造器注入杜絕字段注入循環(huán)依賴(lài)問(wèn)題線程安全性更高? 實(shí)體屬性一律 private遵循 Java 封裝原則適配 JSON 序列化、MyBatis 字段映射? 接口內(nèi)變量默認(rèn) public static final方法默認(rèn) public abstract無(wú)需手動(dòng)書(shū)寫(xiě)。