0

0

深入理解Java NumberFormat的运行时多态性

霞舞

霞舞

发布时间:2025-10-09 13:54:08

|

189人浏览过

|

来源于php中文网

原创

深入理解java numberformat的运行时多态性

本文旨在解析Java NumberFormat类中看似由父类调用子类format方法的现象。核心在于NumberFormat是一个抽象类,其静态工厂方法getCurrencyInstance()返回的是其具体子类(如DecimalFormat)的实例。当通过父类引用调用final的format(long number)方法时,该方法内部会调用父类中声明为抽象的方法,而实际执行的则是子类提供的具体实现,这是Java多态性和抽象类设计的典型体现。

1. NumberFormat与DecimalFormat的类层级关系

在Java中,java.text.NumberFormat是一个抽象类,它定义了格式化和解析数字的通用接口。由于它是抽象的,我们不能直接实例化NumberFormat对象。相反,它提供了静态工厂方法(如getCurrencyInstance()、getNumberInstance()等)来获取其具体子类的实例。

通常情况下,当我们调用NumberFormat.getCurrencyInstance()时,返回的实际对象是一个java.text.DecimalFormat的实例。DecimalFormat是NumberFormat的一个具体子类,它实现了NumberFormat中所有抽象方法,并提供了更丰富的数字格式化功能。

import java.text.NumberFormat;

public class Main {
    public static void main(String[] args) {
        double totalSalaries = 14000;
        // currencyInstance 实际上是 DecimalFormat 的实例,但其类型被声明为 NumberFormat
        NumberFormat currencyInstance = NumberFormat.getCurrencyInstance();

        System.out.printf("The total payout should be %s%n", currencyInstance.format(totalSalaries));
    }
}

在上述代码中,尽管currencyInstance变量被声明为NumberFormat类型,但它实际指向的是一个DecimalFormat对象。这是Java多态性的一个核心特征:父类引用可以指向子类对象。

2. format方法的调用机制解析

当我们通过currencyInstance.format(totalSalaries)调用format方法时,调试器中观察到的调用路径可能令人困惑。表面上看,它似乎先进入NumberFormat类的format方法,然后又跳转到DecimalFormat类的format方法。理解这一过程的关键在于NumberFormat类的设计。

立即学习Java免费学习笔记(深入)”;

2.1 NumberFormat中的final方法

NumberFormat类中定义了一个final修饰的format(long number)方法:

public final String format(long number) {
    // 内部调用另一个抽象的 format 方法
    return format(number, new StringBuffer(),
                  DontCareFieldPosition.INSTANCE).toString();
}

这个方法是final的,意味着子类不能覆盖它。它的作用是提供一个便捷的入口,将long类型的数字格式化为String。然而,这个方法本身并不包含实际的格式化逻辑,它仅仅是调用了NumberFormat类中另一个重载的format方法。

豆包MarsCode
豆包MarsCode

豆包旗下AI编程助手,支持DeepSeek最新模型

下载

2.2 NumberFormat中的抽象方法

NumberFormat类中还声明了一个抽象的format方法:

public abstract StringBuffer format(long number,
                                    StringBuffer toAppendTo,
                                    FieldPosition pos);

由于NumberFormat是一个抽象类,它可以包含抽象方法。这个抽象方法定义了数字格式化的核心逻辑接口,但没有提供具体实现。任何继承NumberFormat并希望成为具体(可实例化)的子类都必须实现这个抽象方法。

2.3 DecimalFormat中的具体实现

DecimalFormat作为NumberFormat的一个具体子类,必须实现其所有抽象方法,包括上述的format方法。以下是DecimalFormat中该方法的简化实现(实际实现可能更复杂):

@Override
public StringBuffer format(long number, StringBuffer result,
                           FieldPosition fieldPosition) {
    // 设置字段位置(通常用于高亮显示特定部分,如小数位)
    fieldPosition.setBeginIndex(0);
    fieldPosition.setEndIndex(0);

    // 实际的格式化逻辑可能进一步委托给其他内部方法
    return format(number, result, fieldPosition.getFieldDelegate());
}

当调试器逐步执行currencyInstance.format(totalSalaries)时,会发生以下情况:

  1. 调用入口: 首先进入NumberFormat类的public final String format(long number)方法。这是因为currencyInstance变量的声明类型是NumberFormat,并且这个final方法是其公共接口的一部分。
  2. 内部委托: final方法内部调用了format(number, new StringBuffer(), DontCareFieldPosition.INSTANCE)。
  3. 多态分派: 尽管这个被调用的format方法在NumberFormat中是抽象的,但由于currencyInstance实际指向的是一个DecimalFormat对象,Java的运行时多态机制会确保调用的是DecimalFormat类中对这个抽象方法的具体实现。

因此,调试器显示先进入NumberFormat的final方法,然后跳到DecimalFormat的@Override方法,这正是Java面向对象设计中多态性(运行时绑定)的体现。父类定义了行为的骨架和接口,而子类提供了具体的实现。

3. 注意事项与总结

  • 抽象类与具体子类: 理解抽象类不能直接实例化,其作用是定义接口和共享通用实现。具体子类负责实现抽象方法。
  • 多态性: 父类引用指向子类对象是Java多态性的核心。方法调用在运行时根据实际对象的类型进行分派。
  • final方法的作用: final方法确保了某些行为在子类中不能被修改,常用于提供稳定的入口或封装内部逻辑。
  • 调试器行为: 调试器会按照实际的方法调用路径进行跟踪。当父类方法内部调用一个抽象方法时,如果实际对象是子类实例,调试器会跳转到子类的具体实现。

通过上述分析,我们可以清楚地看到,NumberFormat类中format方法的调用流程并非父类直接调用子类方法,而是父类方法委托给一个抽象方法,该抽象方法在运行时通过多态机制被实际子类对象所实现和执行。这充分展示了Java在处理复杂类层次结构和行为复用时的强大灵活性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

56

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

52

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

782

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

434

2024.06.27

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

2

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.9万人学习

Java 教程
Java 教程

共578课时 | 52.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号