解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字
  TEZNKK3IfmPf 2023年11月12日 83 0

问题

今天在编程时,产品经理突然和我说,把所有的金额保留两位小数后,传递到前台。一时间,不知道该怎么做,于是,通过百度百科,查找到了DecimalFormat这个类。

解释DecimalFormat

DecimalFormatNumberFormat 的一个具体子类,用于格式化十进制数字,如下代码所示:

import java.math.BigDecimal;
import java.text.DecimalFormat;

/** * Created By zby on 21:03 2022/5/10 */
public class StringObject {
     
       

    public static void main(String[] args) {
     
       
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        String format = decimalFormat.format(new BigDecimal("2.123"));
        System.out.printf("输出结果为:%s", format);

    }
}

上述代码的输出结果为:

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

我们经常使用 DecimalFormat去格式化数字,其中包括金额。

当然,可以通过DecimalFormat(String pattern)去创建当前对象,这里的pattern是设置输出结果的模式。

比如如果输出两位小数,pattern可以为0.00,如上图所示。

若想输出整数,patter可以为0,如下图所示:

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

复现问题

但在项目中使用DecimalFormat这个类时,出现了错误,错误如下:

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

通过谷歌翻译得到:无法将给定对象格式化为数字

重点不是这句话,而是为什么无法将给定的对象格式化数字。

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

如果将String类型转化为BigDecimal类型的,就不会报错:

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

为什么会这样呢?

解决问题

通过查看源码得出,DecimalFormat继承了抽象类NumberFormatNumberFormat继承了抽象类Format,里面各有format方法,我们来看看Format类中的format方法

public abstract StringBuffer format(Object obj,
                    StringBuffer toAppendTo,
                    FieldPosition pos);

这是个未实现的方法,我们点击idea左边的向下箭头,会出现让你惊讶的一幕:

解决Cannot format given Object as a Number问题,理解DecimalFormat.format()方法及使用DecimalFormat保留两位小数的金额和格式化数字

实现该方法的类有很多,而我们今天所说的就DecimalFormat,我们来看看它的实现方法:

 @Override
    public final StringBuffer format(Object number,
                                     StringBuffer toAppendTo,
                                     FieldPosition pos) {
     
       
        if (number instanceof Long || number instanceof Integer ||
                   number instanceof Short || number instanceof Byte ||
                   number instanceof AtomicInteger ||
                   number instanceof AtomicLong ||
                   (number instanceof BigInteger &&
                    ((BigInteger)number).bitLength () < 64)) {
     
       
            return format(((Number)number).longValue(), toAppendTo, pos);
        } else if (number instanceof BigDecimal) {
     
       
            return format((BigDecimal)number, toAppendTo, pos);
        } else if (number instanceof BigInteger) {
     
       
            return format((BigInteger)number, toAppendTo, pos);
        } else if (number instanceof Number) {
     
       
            return format(((Number)number).doubleValue(), toAppendTo, pos);
        } else {
     
       
            throw new IllegalArgumentException("Cannot format given Object as a Number");
        }
    }

你会发现,我们居然找到了上面报错文字: throw new IllegalArgumentException("Cannot format given Object as a Number");

如果你知道instanceof 的话,你就会明白这是该对象是否是某类的实例化对象。这里的有很多包装类,就没有String类和自定义类型,因而,就会出现了错误。所以,它没办法解释格式化String类型的数据。

总结

遇到报错别紧张,查看源码来解析,建议大家使用idea

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

TEZNKK3IfmPf