詳解Java中$符的各種使用場景
前言
在Java編程中,我們會經(jīng)??吹?符的身影
比如經(jīng)常在配置文件中看到$符號作為變量占位符,用于在運(yùn)行時動態(tài)地獲取變量值。
這種做法有助于提高代碼的靈活性和可維護(hù)性。除了在配置文件中使用$符號外,我們還會在其他場景中遇到這個符號,例如內(nèi)部類、Lambda表達(dá)式、自動生成的代碼等。
接下來,我將詳細(xì)介紹$符號在Java編程中的各種應(yīng)用場景,以幫助您更好地理解和運(yùn)用這個符號。
1. $符號七大應(yīng)用場景
1.1 內(nèi)部類與匿名內(nèi)部類
在Java中,當(dāng)一個類被定義在另一個類的內(nèi)部時,它被稱為內(nèi)部類。在編譯之后,內(nèi)部類的字節(jié)碼文件名將包含外部類名、$符號和內(nèi)部類名。例如,如果我們有一個名為Outer的外部類和一個名為Inner的內(nèi)部類,那么編譯后的字節(jié)碼文件名為:Outer$Inner.class。同樣,當(dāng)我們創(chuàng)建匿名內(nèi)部類時,編譯器會為其生成一個類名,該類名包含外部類名、$符號以及一個編譯器生成的數(shù)字序列,例如:Outer$1.class。
1.2 Lambda表達(dá)式與方法引用
從Java 8開始,Lambda表達(dá)式和方法引用成為了Java編程的重要組成部分。當(dāng)編譯器處理Lambda表達(dá)式和方法引用時,它會生成包含$符號的特殊方法名。例如,考慮以下Lambda表達(dá)式:
Runnable r = () -> System.out.println("Hello, world!");
編譯后,將生成一個名為lambda$main$0的方法。在這種情況下,$符號用于區(qū)分由編譯器生成的Lambda表達(dá)式方法和其他程序中的方法。
1.3. 自動生成的字段與方法
在某些情況下,Java編譯器會為我們自動生成一些字段和方法,這些字段和方法的名字可能包含$符號。例如,當(dāng)我們使用枚舉類型(Enum)時,編譯器會為枚舉類生成一個名為$VALUES的靜態(tài)字段,以及一個名為valueOf的靜態(tài)方法。同樣,當(dāng)我們使用switch語句與枚舉類型結(jié)合時,編譯器會生成一個包含$符號的方法,用于實現(xiàn)對應(yīng)的switch邏輯。
1.4. 自定義類名與變量名
雖然在Java編程中,通常不建議使用$符號作為類名或變量名的一部分,但這是允許的。例如,以下代碼是有效的Java代碼:
class MyClass$1 { int $value = 42; }
然而,由于這種命名方法可能引起混淆,因此在實際編程中應(yīng)該避免這樣做。
1.5. 生成的代碼和工具
在某些情況下,代碼生成工具(如AspectJ,JAXB等)和字節(jié)碼處理庫(如ASM,CGLIB等)可能會在生成的類名、方法名或字段名中使用$符號。這是因為$符號在這些場景下能夠提供一種有效的命名約定,避免與原始代碼中的名稱發(fā)生沖突。
1.6. 貨幣計算
在Java程序中,我們可能會使用BigDecimal或其他數(shù)據(jù)類型處理貨幣計算。在某些情況下,我們可以使用$符號作為貨幣值的前綴,以表示貨幣單位。雖然這不是Java語言的內(nèi)置功能,但是可以作為一種編程約定來使用,以提高代碼的可讀性。
BigDecimal salary = new BigDecimal("5000.00"); BigDecimal bonus = new BigDecimal("1000.00"); BigDecimal total = salary.add(bonus); System.out.println("Total: $" + total);
雖然這里的$符號并不是Java語言特性,但它在表示貨幣值時可以幫助提高代碼的可讀性。
1.7 在配置文件中動態(tài)獲取變量值
在Java應(yīng)用程序中,我們經(jīng)常需要使用配置文件來存儲和管理應(yīng)用程序的設(shè)置。在許多情況下,配置文件會使用$符號作為占位符,用于動態(tài)獲取變量值。以下是一些常見的配置文件格式和$符號的使用示例:
1.7.1 Java屬性文件(.properties)
Java屬性文件是一種簡單的鍵值存儲格式。在屬性文件中,我們可以使用${key}的形式作為占位符,表示需要從其他地方獲取值。
database.url = jdbc:mysql://${host}:${port}/${dbName}
在這個例子中,${host}、${port}和${dbName}是占位符,它們將在運(yùn)行時被相應(yīng)的值替換。
1.7.2 Spring Boot配置文件(application.yml 或 application.properties)
在Spring Boot應(yīng)用程序中,我們通常使用YAML或?qū)傩晕募砼渲脩?yīng)用程序。在這些文件中,我們可以使用$符號和大括號來表示占位符。
server: port: ${app.port:8080}
在這個例子中,${app.port:8080}表示一個占位符,其值將在運(yùn)行時從環(huán)境變量或其他配置源中獲取。如果沒有找到該值,將使用默認(rèn)值8080。
1.7.3 Apache Maven POM文件(pom.xml)
Apache Maven是一種流行的Java構(gòu)建工具。在Maven的POM文件中,我們可以使用$符號和大括號來表示占位符。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> </properties>
在這個例子中,${java.version}表示一個占位符,其值將在運(yùn)行時從其他地方獲取。
1.7.4 Java模板引擎(如Thymeleaf, FreeMarker, Velocity等)
在Java Web應(yīng)用程序中,我們經(jīng)常使用模板引擎來渲染HTML頁面。許多模板引擎都支持使用$符號作為占位符,用于動態(tài)獲取變量值。
<!-- Thymeleaf 示例 --> <p th:text="${message}"></p> <!-- FreeMarker 示例 --> <p>${message}</p> <!-- Velocity 示例 --> <p>$message</p>
在這些例子中,$符號用于動態(tài)插入變量message的值。
1.7.5 Log4j2 配置文件中動態(tài)獲取變量值
Log4j2是一個流行的Java日志框架,用于記錄應(yīng)用程序的運(yùn)行狀況。在Log4j2的配置文件中,我們可以使用$符號和大括號作為占位符,用于動態(tài)獲取變量值。以下是一個Log4j2配置文件(log4j2.xml)的示例:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Properties> <Property name="logPath">${sys:user.home}/logs</Property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </Console> <RollingFile name="RollingFile" fileName="${logPath}/app.log" filePattern="${logPath}/app-%d{yyyy-MM-dd}.log.gz"> <PatternLayout> <pattern>%d %p %c{1.} [%t] %m%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console" /> <AppenderRef ref="RollingFile" /> </Root> </Loggers> </Configuration>
在這個例子中,我們使用${sys:user.home}作為占位符,表示用戶主目錄。在運(yùn)行時,這個占位符將被相應(yīng)的系統(tǒng)屬性值替換。同時,我們還定義了一個名為logPath的自定義屬性,它的值為${sys:user.home}/logs。在配置文件的其他部分,我們可以使用${logPath}來引用這個屬性。
2. 在配置文件中$符號來獲取變量值的原理
在配置文件中使用$符號獲取變量值,其背后的原理主要包括解析占位符、變量替換和值來源。以下是詳細(xì)說明:
- 解析占位符: 配置文件中的占位符通常以$符號開頭,后跟一對大括號({}),括號內(nèi)包含變量名。例如,${variable}。在加載配置文件時,解析器會識別這種格式的占位符,并提取其中的變量名。
- 變量替換: 解析器識別并提取占位符后,需要在運(yùn)行時將其替換為實際的變量值。具體的替換過程取決于配置文件的格式和使用的庫。例如,Java屬性文件的解析器可能使用java.util.Properties類來完成變量替換,而Spring Boot配置文件的解析器可能使用Spring框架提供的PropertySourcesPlaceholderConfigurer類來完成替換。
- 值來源: 變量值的來源可能有多種,例如環(huán)境變量、系統(tǒng)屬性、外部配置文件等。解析器需要知道在哪里查找變量值。這通常是通過配置文件解析器的特性或規(guī)則來實現(xiàn)的。例如,在Java屬性文件中,解析器可能首先查找系統(tǒng)屬性,然后查找環(huán)境變量;而在Spring Boot配置文件中,解析器會按照特定的順序查找多個PropertySource,這些PropertySource可以來自環(huán)境變量、系統(tǒng)屬性、配置文件等。
- 默認(rèn)值和條件替換: 在某些情況下,配置文件解析器還支持為占位符提供默認(rèn)值或進(jìn)行條件替換。例如,Spring Boot的配置文件解析器允許我們使用:符號為占位符指定默認(rèn)值,如${variable:defaultValue}。如果在運(yùn)行時找不到variable的值,解析器將使用defaultValue作為替換值。此外,Spring Boot還支持@Conditional注解,這允許我們根據(jù)條件選擇性地應(yīng)用配置。
3. 為什么要是用$符而不使用別的符號
在配置文件中使用$符號作為變量占位符的原因可以從歷史、約定和可讀性等方面來解釋。
- 歷史原因: Unix和Linux操作系統(tǒng)中,環(huán)境變量的表示方法是以美元符號($)作為前綴,例如$PATH。這種表示法在很大程度上影響了其他技術(shù)的設(shè)計,包括各種配置文件格式。在很多配置文件中沿用$符號作為變量占位符,這是受到了Unix和Linux環(huán)境變量表示法的影響。
- 約定俗成: 多年來,程序員們在各種配置文件和模板引擎中使用$符號作為變量占位符。這已經(jīng)成為一種廣泛接受的編程慣例。當(dāng)大多數(shù)開發(fā)者都習(xí)慣于這種表示法時,繼續(xù)使用$符號可以降低學(xué)習(xí)曲線,使新的配置文件格式更容易被接受。
- 可讀性: 在實際編程中,可讀性是一個重要的考慮因素。$符號在許多編程語言和配置文件中具有特殊含義,它很容易引起開發(fā)者的注意。使用$符號作為占位符可以提高配置文件的可讀性,有助于開發(fā)者快速理解代碼的含義。
- 避免沖突: 配置文件中的變量占位符需要使用一種不容易與其他文本內(nèi)容混淆的符號。$符號在很多編程語言中具有特殊含義,因此在配置文件中使用$符號作為變量占位符可以減少與其他字符的沖突。
小結(jié)
總之,配置文件中$符號獲取變量值的原理涉及到解析占位符、變量替換和值來源。通過在配置文件中使用$符號作為占位符,我們可以實現(xiàn)動態(tài)配置管理,從而提高代碼的可讀性和可維護(hù)性。不同的配置文件格式和庫可能有不同的實現(xiàn)細(xì)節(jié),但其背后的基本原理是相似的。
盡管$符號在配置文件中作為變量占位符有一定的優(yōu)勢,但并非所有的配置文件格式都使用$符號。有些配置文件可能會選擇其他符號或表示法,這主要取決于設(shè)計者的偏好和目標(biāo)。然而,在許多流行的配置文件和模板引擎中,$符號已經(jīng)成為一種廣泛使用的占位符。
以上就是詳解Java中$符的各種使用場景的詳細(xì)內(nèi)容,更多關(guān)于Java $符的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一篇文章教你使用SpringBoot如何實現(xiàn)定時任務(wù)
這篇文章主要給大家介紹了關(guān)于如何利用一篇文章教你使用SpringBoot實現(xiàn)定時任務(wù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10java hibernate使用注解來定義聯(lián)合主鍵
這篇文章主要介紹了java hibernate使用注解來定義聯(lián)合主鍵的相關(guān)資料,需要的朋友可以參考下2017-01-01詳解spring cloud如何使用spring-test進(jìn)行單元測試
這篇文章主要介紹了spring cloud如何使用spring-test進(jìn)行單元測試,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11java實現(xiàn)服務(wù)器文件打包zip并下載的示例(邊打包邊下載)
這篇文章主要介紹了java實現(xiàn)服務(wù)器文件打包zip并下載的示例,使用該方法,可以即時打包文件,一邊打包一邊傳輸,不使用任何的緩存,讓用戶零等待,需要的朋友可以參考下2014-04-04Java中的使用及連接Redis數(shù)據(jù)庫(附源碼)
這篇文章主要介紹了Java中的使用及連接Redis數(shù)據(jù)庫(附源碼),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09使用ElasticSearch6.0快速實現(xiàn)全文搜索功能的示例代碼
本篇文章主要介紹了使用ElasticSearch6.0快速實現(xiàn)全文搜索功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02