闲聊Java中$符的各种使用场景

news/2024/4/27 1:17:02/文章来源:https://blog.csdn.net/qq_34050399/article/details/130338572

前言

在Java编程中,我们会经常看到$符的身影,比如经常在配置文件中看到$符号作为变量占位符,用于在运行时动态地获取变量值。这种做法有助于提高代码的灵活性和可维护性。除了在配置文件中使用$符号外,我们还会在其他场景中遇到这个符号,例如内部类、Lambda表达式、自动生成的代码等。接下来,我将详细介绍$符号在Java编程中的各种应用场景,以帮助您更好地理解和运用这个符号。

1. $符号七大应用场景

1.1 内部类与匿名内部类

在Java中,当一个类被定义在另一个类的内部时,它被称为内部类。在编译之后,内部类的字节码文件名将包含外部类名、$符号和内部类名。例如,如果我们有一个名为Outer的外部类和一个名为Inner的内部类,那么编译后的字节码文件名为:Outer$Inner.class。同样,当我们创建匿名内部类时,编译器会为其生成一个类名,该类名包含外部类名、$符号以及一个编译器生成的数字序列,例如:Outer$1.class。

1.2 Lambda表达式与方法引用

从Java 8开始,Lambda表达式和方法引用成为了Java编程的重要组成部分。当编译器处理Lambda表达式和方法引用时,它会生成包含$符号的特殊方法名。例如,考虑以下Lambda表达式:

Runnable r = () -> System.out.println("Hello, world!");

编译后,将生成一个名为lambda$main$0的方法。在这种情况下,$符号用于区分由编译器生成的Lambda表达式方法和其他程序中的方法。

1.3. 自动生成的字段与方法

在某些情况下,Java编译器会为我们自动生成一些字段和方法,这些字段和方法的名字可能包含$符号。例如,当我们使用枚举类型(Enum)时,编译器会为枚举类生成一个名为$VALUES的静态字段,以及一个名为valueOf的静态方法。同样,当我们使用switch语句与枚举类型结合时,编译器会生成一个包含$符号的方法,用于实现对应的switch逻辑。

1.4. 自定义类名与变量名

虽然在Java编程中,通常不建议使用$符号作为类名或变量名的一部分,但这是允许的。例如,以下代码是有效的Java代码:

class MyClass$1 {int $value = 42;
}

然而,由于这种命名方法可能引起混淆,因此在实际编程中应该避免这样做。

1.5. 生成的代码和工具

在某些情况下,代码生成工具(如AspectJ,JAXB等)和字节码处理库(如ASM,CGLIB等)可能会在生成的类名、方法名或字段名中使用$符号。这是因为$符号在这些场景下能够提供一种有效的命名约定,避免与原始代码中的名称发生冲突。

1.6. 货币计算

在Java程序中,我们可能会使用BigDecimal或其他数据类型处理货币计算。在某些情况下,我们可以使用$符号作为货币值的前缀,以表示货币单位。虽然这不是Java语言的内置功能,但是可以作为一种编程约定来使用,以提高代码的可读性。

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 在配置文件中动态获取变量值

在Java应用程序中,我们经常需要使用配置文件来存储和管理应用程序的设置。在许多情况下,配置文件会使用$符号作为占位符,用于动态获取变量值。以下是一些常见的配置文件格式和$符号的使用示例:

1.7.1 Java属性文件(.properties)

Java属性文件是一种简单的键值存储格式。在属性文件中,我们可以使用${key}的形式作为占位符,表示需要从其他地方获取值。

database.url = jdbc:mysql://${host}:${port}/${dbName}

在这个例子中,${host}、${port}和${dbName}是占位符,它们将在运行时被相应的值替换。

1.7.2 Spring Boot配置文件(application.yml 或 application.properties)

在Spring Boot应用程序中,我们通常使用YAML或属性文件来配置应用程序。在这些文件中,我们可以使用$符号和大括号来表示占位符。

server:port: ${app.port:8080}

在这个例子中,${app.port:8080}表示一个占位符,其值将在运行时从环境变量或其他配置源中获取。如果没有找到该值,将使用默认值8080。

1.7.3 Apache Maven POM文件(pom.xml)

Apache Maven是一种流行的Java构建工具。在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}表示一个占位符,其值将在运行时从其他地方获取。

1.7.4 Java模板引擎(如Thymeleaf, FreeMarker, Velocity等)

在Java Web应用程序中,我们经常使用模板引擎来渲染HTML页面。许多模板引擎都支持使用$符号作为占位符,用于动态获取变量值。

<!-- Thymeleaf 示例 -->
<p th:text="${message}"></p><!-- FreeMarker 示例 -->
<p>${message}</p><!-- Velocity 示例 -->
<p>$message</p>

在这些例子中,$符号用于动态插入变量message的值。

1.7.5 Log4j2 配置文件中动态获取变量值

Log4j2是一个流行的Java日志框架,用于记录应用程序的运行状况。在Log4j2的配置文件中,我们可以使用$符号和大括号作为占位符,用于动态获取变量值。以下是一个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}作为占位符,表示用户主目录。在运行时,这个占位符将被相应的系统属性值替换。同时,我们还定义了一个名为logPath的自定义属性,它的值为${sys:user.home}/logs。在配置文件的其他部分,我们可以使用${logPath}来引用这个属性。

2. 在配置文件中$符号来获取变量值的原理

在配置文件中使用$符号获取变量值,其背后的原理主要包括解析占位符、变量替换和值来源。以下是详细说明:

  • 解析占位符:
    配置文件中的占位符通常以$符号开头,后跟一对大括号({}),括号内包含变量名。例如,${variable}。在加载配置文件时,解析器会识别这种格式的占位符,并提取其中的变量名。

  • 变量替换:
    解析器识别并提取占位符后,需要在运行时将其替换为实际的变量值。具体的替换过程取决于配置文件的格式和使用的库。例如,Java属性文件的解析器可能使用java.util.Properties类来完成变量替换,而Spring Boot配置文件的解析器可能使用Spring框架提供的PropertySourcesPlaceholderConfigurer类来完成替换。

  • 值来源:
    变量值的来源可能有多种,例如环境变量、系统属性、外部配置文件等。解析器需要知道在哪里查找变量值。这通常是通过配置文件解析器的特性或规则来实现的。例如,在Java属性文件中,解析器可能首先查找系统属性,然后查找环境变量;而在Spring Boot配置文件中,解析器会按照特定的顺序查找多个PropertySource,这些PropertySource可以来自环境变量、系统属性、配置文件等。

  • 默认值和条件替换:
    在某些情况下,配置文件解析器还支持为占位符提供默认值或进行条件替换。例如,Spring Boot的配置文件解析器允许我们使用:符号为占位符指定默认值,如${variable:defaultValue}。如果在运行时找不到variable的值,解析器将使用defaultValue作为替换值。此外,Spring Boot还支持@Conditional注解,这允许我们根据条件选择性地应用配置。

3. 为什么要是用$符而不使用别的符号?

在配置文件中使用$符号作为变量占位符的原因可以从历史、约定和可读性等方面来解释。

  • 历史原因:
    Unix和Linux操作系统中,环境变量的表示方法是以美元符号($)作为前缀,例如$PATH。这种表示法在很大程度上影响了其他技术的设计,包括各种配置文件格式。在很多配置文件中沿用$符号作为变量占位符,这是受到了Unix和Linux环境变量表示法的影响。

  • 约定俗成:
    多年来,程序员们在各种配置文件和模板引擎中使用$符号作为变量占位符。这已经成为一种广泛接受的编程惯例。当大多数开发者都习惯于这种表示法时,继续使用$符号可以降低学习曲线,使新的配置文件格式更容易被接受。

  • 可读性:
    在实际编程中,可读性是一个重要的考虑因素。$符号在许多编程语言和配置文件中具有特殊含义,它很容易引起开发者的注意。使用$符号作为占位符可以提高配置文件的可读性,有助于开发者快速理解代码的含义。

  • 避免冲突:
    配置文件中的变量占位符需要使用一种不容易与其他文本内容混淆的符号。$符号在很多编程语言中具有特殊含义,因此在配置文件中使用$符号作为变量占位符可以减少与其他字符的冲突。

小结

总之,配置文件中$符号获取变量值的原理涉及到解析占位符、变量替换和值来源。通过在配置文件中使用$符号作为占位符,我们可以实现动态配置管理,从而提高代码的可读性和可维护性。不同的配置文件格式和库可能有不同的实现细节,但其背后的基本原理是相似的。

尽管$符号在配置文件中作为变量占位符有一定的优势,但并非所有的配置文件格式都使用$符号。有些配置文件可能会选择其他符号或表示法,这主要取决于设计者的偏好和目标。然而,在许多流行的配置文件和模板引擎中,$符号已经成为一种广泛使用的占位符。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_102568.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解树与二叉树的概念,结构,及实现(上篇)

目录 一&#xff0c; 树 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 二&#xff0c; 二叉树 2.1二叉树概念 三&#xff0c;特殊的二叉树 1. 满二叉树 2. 完全二叉树 3. 1 二叉树的性质 3. 2 二叉树的存储…

【速卖通】 AliExpress(速卖通)关键词搜索结果采集

采集场景 在AliExpress(速卖通) 首页中 http://www.aliexpress.com 中输入关键词&#xff0c;采集关键词搜索后得到的商品列表信息。 采集字段 关键词、标题、商品id、商品图片地址、商品详情链接、价格、免费退送货、星级、已出售数量、店铺名 采集结果 采集结果可导出为E…

Linux-初学者系列——篇幅7_文本编辑和处理命令

文本编辑和处理命令-目录 一、系统基本编辑命令安装vim软件工具包语法格式&#xff1a; 1、vim编辑命令模式01 普通模式02 编辑模式03 命令模式 2、编辑文件技巧01 批量删除多行指定信息02 批量增加多列指定信息03 编辑常见问题错误1&#xff1a;没有指定编辑信息错误2&#xf…

基于TensorRT的yolov5 实例分割部署

yolov5-7.0 github: https://github.com/ultralytics/yolov5/tree/master 1. 代码的使用 1.1 训练yolov5-seg模型 使用的yolov5-7.0的代码,github下载:https://github.com/ultralytics/yolov5/releases/tag/v7.0 训练指令 python segment/train.py --data coco128-seg.y…

centos7 查看服务器配置信息

1.linux查看版本当前操作系统发行信息 cat /etc/centos-release cat /etc/centos-release 2、查看内核版本uname -a或者cat /proc/version 3、查看CPU参数 1&#xff09;、查看 CPU 物理个数   grep physical id /proc/cpuinfo | sort -u | wc -l 2&#xff09;、查看 CPU …

SpringCloud:ElasticSearch之DSL查询文档

elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;一般测试用。例如…

magento webapi 接口返回 json对象

前言 现在主流的项目开发都是前后端分离&#xff0c;数据通过json对象格式进行传输。但是magento框架&#xff0c;和传统PHP框架相比&#xff0c;区别很大。虽然也支持以RestApi的形式传输数据&#xff0c;但是要么格式并非是传统jsonObject要么就是需要大量的get、set方法。本…

关于xilinx使用PCIE实现FPGA的部分重配置实现(MCAP)

平台&#xff1a;vivado21018.3 芯片&#xff1a;xcku115-flva1517-2-i (active) 本文官方文档&#xff1a;Xilinx_Answer_64761_Ultrascale_Devices 本文驱动下载地址&#xff1a;64761 - Bitstream Loading across the PCI Express Link in UltraScale and UltraScale Dev…

JAVA——线程池

目录 一、线程池的概念 二、Java标准库中的线程池 三、ThreadPoolExecutor 类的参数 四、线程池的拒绝策略 五、模拟实现线程池 一、线程池的概念 线程池顾名思义就是集中存储线程的地方——联想一下水池。 线程池是一种多线程处理形式&#xff0c;处理过程中将任务添加到…

Ext4日志优化-iJournaling

背景 这几年随着SSD等高性能介质的普及&#xff0c;及其在大规模分布式存储系统上的应用。基于Append only的日志写入技术也应用得越来越多&#xff0c;这几天刚好有空&#xff0c;重读了Ext4文件系统的日志部分的内容&#xff0c;也正好看到一篇对Ext4日志技术进行优化的论文…

《编码——隐藏在计算机软硬件背后的语言》精炼——第11章(门)

“The only source of knowledge is experience.” - Albert Einstein 引言 编码是一种处理并表达信息的方式&#xff0c;它包括摩斯电码、盲文、二进制语言等等&#xff0c;当然作为计算机类的经典书籍&#xff0c;这本书简述了计算机中以二进制数为基础的编码方式&#xff0…

nginx简单介绍

文章目录 1. 下载并解压2. 80端口被占用&#xff0c;更改nginx默认的监听端口3. 访问nginx4. 在linux上安装nginx5. nginx常用命令6. nginx.conf 1. 下载并解压 官网下载 2. 80端口被占用&#xff0c;更改nginx默认的监听端口 更改conf/nginx.conf文件 3. 访问nginx ht…

【Linux】popen pclose接口介绍

本篇文章简单讲述了c语言接口popen/pclose的用法 1.函数作用 函数定义如下 #include <stdio.h>FILE *popen(const char *command, const char *type); int pclose(FILE *stream);1.1 popen popen函数会创建一个管道&#xff0c;fork后调用shell来打开进程。由于管道的…

射频封装技术:层压基板和无源器件集成

射频和无线产品领域可以使用非常广泛的封装载体技术&#xff0c;它们包括引线框架、层压基板、低温共烧陶瓷&#xff08;LTCC&#xff09;和硅底板载体&#xff08;Si Backplane&#xff09;。由于不断增加的功能对集成度有了更高要求&#xff0c;市场对系统级封装方法&#xf…

Qt 项目Mingw编译器转换为VS编译器时的错误及解决办法

错误 在mingw生成的项目&#xff0c;转换为VS编译器时通常会报些以下错误&#xff08;C4819警告&#xff0c;C2001错误&#xff0c;C2143错误&#xff09; 原因及解决方式 这一般是由于字符编码引起的&#xff0c;在源代码文件中包含了中文字符导致的。Qt Creator 生成的代码文…

iptables防火墙和Firewalld

引言 在 Internet 中&#xff0c;企业通过各种应用系统来为用户提供各种服务&#xff0c;如 Web 网站、电子邮件系统、FTP 服务器、数据库系统等&#xff0c;那么&#xff0c;如何来保护这些服务器&#xff0c;过滤企业不需要的访问甚至是恶意的入侵呢&#xff0c;接下来&#…

【Linux】生产者消费者模型——环形队列RingQueue(信号量)

文章目录 铺垫信号量信号量概念信号量PV操作信号量基本接口 环形队列的生产消费模型引入环形队列访问环形队列代码实现代码改造多生产者多消费者代码 总结 铺垫 之前写的代码是存在不足的地方的&#xff1a; 我们使用线程操作临界资源的时候要先去判断临界资源是否满足条件&am…

最新动态 | 大势智慧参加广东省应急测绘保障与安全生产演练

4月20日&#xff0c;2023年度广东省应急测绘保障与安全生产演练在台山市赤溪镇鱼塘湾举行。本次演练由广东自然资源厅主办&#xff0c;广东省国土资源测绘院、江门市自然资源局和台山市人民政府承办。在省市各指导单位与参演单位的多方协同与指挥下&#xff0c;应急测绘保障与安…

【三十天精通Vue 3】第十四天 Vue 3 的单元测试详解

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: 三十天精通 Vue 3 文章目录 引言一、为什么要进行单元测试1.1 单元测试的概念1.2 单元测试的优…

ctfshow_WEB_web2 wp

前言 写这个是因为。。。我想摆烂&#xff0c;就去从最简单的题开始做了&#xff0c;想着交一道题是一道嘛&#xff0c;总之觉得这样做很适合欺骗安慰自己&#xff08;逃 然后我发现我错了&#xff0c;我第二道题就做了好久还没做出来&#xff0c;甚至最后去点开了hint…… ps…