ZetCode

Java Number 类

最后修改时间:2025 年 4 月 13 日

java.lang.Number 类是 Java 中所有数值包装类的抽象超类。 它是处理不同数值类型(包括 IntegerDoubleFloatLongShortByte)的基础。 了解 Number 类对于执行数值转换和使用原始值的面向对象表示至关重要。

Number 类提供了将数值转换为各种原始类型的方法。 这些方法由所有数值包装子类实现,确保无缝类型转换。 作为原始数值类型及其对象对应项之间的桥梁,Number 类简化了数值数据的操作,同时保持了灵活性。

Number 类的关键方法

Number 类定义了其子类必须实现的基本抽象方法。 这些方法通过返回数值的原始表示形式来促进类型转换。 主要方法包括

通过实现这些方法,数值包装类提供了处理不同数据类型的便捷方式,同时保留了面向对象的原则。

在实践中,Number 类对于编写通用的、灵活的代码至关重要,这些代码可以无缝处理各种数值类型,而无需提前了解特定的类型。 这使得它在需要多态性的场景中特别有价值,例如设计 API、集合或动态处理不同数值类型的实用程序方法。

例如,API 可能需要接受不同的数值输入 - 无论是 IntegerDouble 还是 Float - 而无需强制执行严格的类型依赖性。 通过使用 Number 作为参数或返回类型,开发人员可以确保他们的代码保持适应性,能够支持多种数值类型而无需进行大量的类型检查逻辑。 这种方法增强了代码的可重用性和可扩展性,使其更容易扩展功能,同时保持强大的类型安全性。

此外,由于所有数值包装类都实现了 Number 中定义的转换方法,开发人员可以使用 intValuedoubleValuelongValuefloatValue 等方法轻松地在原始类型之间切换。 这允许在数学运算、计算和数据处理工作流程中进行平滑的类型转换,确保精度,同时遵守面向对象的设计原则。

总的来说,在通用编程中利用 Number 类可以培养模块化、可维护和高效的代码,帮助开发人员处理各种数值类型,而不会牺牲灵活性或性能。

基本 Number 用法

Number 类是抽象的,因此我们使用它的具体子类,如 IntegerDouble。 此示例演示了将 Number 引用与不同数值类型一起使用的基本用法。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {
        
        Number num1 = Integer.valueOf(42);
        Number num2 = Double.valueOf(3.14);
        Number num3 = Float.valueOf(2.718f);
        
        System.out.println("Integer value: " + num1.intValue());
        System.out.println("Double value: " + num2.doubleValue());
        System.out.println("Float value: " + num3.floatValue());
        
        // Using Number as a common type
        Number[] numbers = {num1, num2, num3};
        for (Number num : numbers) {
            System.out.println("Number value: " + num.doubleValue());
        }
    }
}

在此示例中,我们创建对不同数值类型的 Number 引用。 然后,我们演示如何使用转换方法访问值。 Number 数组展示了如何将 Number 用作不同数值类的公共类型。

Number 转换

Number 类提供了在不同数值类型之间进行转换的方法。 此示例显示了数值类型之间的各种转换方案。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {
        
        Number num = Double.valueOf(123.456);
        
        // Converting to different types
        int intVal = num.intValue();
        long longVal = num.longValue();
        float floatVal = num.floatValue();
        double doubleVal = num.doubleValue();
        
        System.out.println("int: " + intVal);
        System.out.println("long: " + longVal);
        System.out.println("float: " + floatVal);
        System.out.println("double: " + doubleVal);
        
        // Potential loss of precision
        Number bigNum = Double.valueOf(1.23e50);
        System.out.println("Big double as float: " + bigNum.floatValue());
    }
}

此示例演示了将 Double Number 转换为各种原始类型。 请注意,转换可能会导致精度损失,尤其是在将大数转换为 float 时。 该示例显示了精确转换和有损转换。

Number 解析

虽然 Number 本身不提供解析方法,但其子类提供解析方法。 此示例演示了如何使用不同的数值类型将字符串解析为 Number 对象。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {
        
        try {
            // Parsing different number types
            Number intNum = Integer.valueOf("42");
            Number doubleNum = Double.valueOf("3.14159");
            Number floatNum = Float.valueOf("2.71828");
            
            System.out.println("Parsed Integer: " + intNum.intValue());
            System.out.println("Parsed Double: " + doubleNum.doubleValue());
            System.out.println("Parsed Float: " + floatNum.floatValue());
            
            // Hexadecimal parsing
            Number hexNum = Integer.valueOf("FF", 16);
            System.out.println("Hexadecimal FF: " + hexNum.intValue());
            
        } catch (NumberFormatException e) {
            System.out.println("Invalid number format: " + e.getMessage());
        }
    }
}

此示例演示了如何使用不同数值包装类的 valueOf 方法将字符串解析为 Number 对象。 它还显示了十六进制解析,并包括对无效数字格式的错误处理。

Number 比较

由于不同的数值类型,比较 Number 对象需要小心。 使用 Integer.valueOf(100)Double.valueOf(100.0) 或自动装箱(例如,Number num = 100)来创建包装对象。 此示例演示了如何通过将 Number 对象转换为通用类型来正确比较它们。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {
        
        Number num1 = Integer.valueOf(100);
        Number num2 = Double.valueOf(100.0);
        Number num3 = Float.valueOf(100.0f);
        
        // Comparing as doubles for precision
        System.out.println("num1 == num2: " + 
            (num1.doubleValue() == num2.doubleValue()));
        System.out.println("num1 == num3: " + 
            (num1.doubleValue() == num3.doubleValue()));
            
        // Comparing with epsilon for floating point
        double epsilon = 0.0001;
        Number floatNum = Float.valueOf(1.0f / 3.0f);
        Number doubleNum = Double.valueOf(1.0 / 3.0);
        
        System.out.println("Float vs Double exact: " + 
            (floatNum.doubleValue() == doubleNum.doubleValue()));
        System.out.println("Float vs Double with epsilon: " + 
            (Math.abs(floatNum.doubleValue() - doubleNum.doubleValue()) < epsilon));
    }
}

此示例演示了 Number 对象的正确比较技术。 它显示了转换为通用类型 (double) 以进行比较,并使用 epsilon 进行浮点比较以解决类型之间的精度差异。

Number 算术

使用 Number 对象执行算术运算需要转换为原始类型。 此示例演示了如何使用不同的 Number 类型安全地执行算术运算。

Main.java
package com.zetcode;

public class Main {

    public static void main(String[] args) {
        
        Number num1 = Integer.valueOf(10);
        Number num2 = Double.valueOf(3.5);
        
        // Performing arithmetic by converting to appropriate types
        double sum = num1.doubleValue() + num2.doubleValue();
        double product = num1.intValue() * num2.doubleValue();
        double division = num1.doubleValue() / num2.doubleValue();
        
        System.out.println("Sum: " + sum);
        System.out.println("Product: " + product);
        System.out.println("Division: " + division);
        
        // Handling different numeric types
        Number[] numbers = {Integer.valueOf(5), Double.valueOf(2.5), Float.valueOf(1.5f)};
        double total = 0;
        for (Number num : numbers) {
            total += num.doubleValue();
        }
        System.out.println("Total: " + total);
    }
}

此示例演示了如何通过将 Number 对象转换为适当的原始类型来执行算术运算。 它演示了加法、乘法和除法,以及对混合 Number 类型的数组求和。

数字格式化

可以使用 NumberFormatDecimalFormat 格式化 Number 对象以进行显示。 此示例演示了 Number 对象的不同格式化选项。

Main.java
package com.zetcode;

import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.util.Locale;

public class Main {

    public static void main(String[] args) {
        
        Number num = Double.valueOf(12345.6789);
        
        // Default locale formatting
        NumberFormat defaultFormat = NumberFormat.getInstance();
        System.out.println("Default format: " + defaultFormat.format(num));
        
        // Currency formatting
        NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
        System.out.println("Currency format: " + currencyFormat.format(num));
        
        // Percentage formatting
        Number percentNum = Double.valueOf(0.85);
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        System.out.println("Percent format: " + percentFormat.format(percentNum));
        
        // Custom decimal formatting
        DecimalFormat decimalFormat = new DecimalFormat("#,##0.00");
        System.out.println("Custom format: " + decimalFormat.format(num));
        
        // Locale-specific formatting
        NumberFormat frenchFormat = NumberFormat.getInstance(Locale.FRANCE);
        System.out.println("French format: " + frenchFormat.format(num));
    }
}

此示例演示了格式化 Number 对象以进行显示的各种方法。 它显示了默认数字格式、货币格式、百分比格式、自定义十进制格式以及使用不同区域设置的特定于区域设置的格式。

Number 和集合

在处理混合数值类型的集合时,Number 类非常有用。 此示例演示了如何处理包含不同 Number 实现的集合。

Main.java
package com.zetcode;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        
        List<Number> numbers = new ArrayList<>();
        numbers.add(Integer.valueOf(42));
        numbers.add(Double.valueOf(3.14159));
        numbers.add(Float.valueOf(2.71828f));
        numbers.add(Long.valueOf(1000000000L));
        
        // Processing mixed numbers
        double sum = 0;
        for (Number num : numbers) {
            sum += num.doubleValue();
            System.out.println("Processing: " + num.getClass().getSimpleName() + 
                             " with value: " + num);
        }
        
        System.out.println("Total sum: " + sum);
        System.out.println("Average: " + (sum / numbers.size()));
        
        // Finding maximum value
        double max = Double.MIN_VALUE;
        for (Number num : numbers) {
            if (num.doubleValue() > max) {
                max = num.doubleValue();
            }
        }
        System.out.println("Maximum value: " + max);
    }
}

此示例演示了如何处理混合 Number 类型的集合。 它显示了如何处理每个数字,而不管其具体类型如何,计算总和和平均值,并通过转换为通用类型 (double) 找到集合中的最大值。

来源

Java Number 类文档

在本文中,我们通过实际示例介绍了 Java Number 类。 了解 Number 对于在 Java 集合和 API 中处理数值转换和混合数值类型至关重要。

作者

我叫 Jan Bodnar,是一位拥有多年领域经验的敬业程序员。 我于 2007 年开始撰写编程文章,此后撰写了超过 1,400 篇文章和八本电子书。 凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程