Java 使用 DecimalFormat 进行格式化会引发异常 - “无法将给定的对象格式化为数字”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45274167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Formatting using DecimalFormat throws exception - "Cannot format given Object as a Number"
提问by Arun Sudhakaran
This might look like a repeated question but I tried in all the below links and can't get a proper answer.
这可能看起来像是一个重复的问题,但我尝试了以下所有链接,但无法得到正确答案。
Cannot format given Object as a Number ComboBox
But I'm not getting what's wrong. Here is my code
但我不明白出了什么问题。这是我的代码
DecimalFormat twoDForm = new DecimalFormat("#.##");
double externalmark = 1.86;
double internalmark = 4.0;
System.out.println(String.valueOf((externalmark*3+internalmark*1)/4));
String val = String.valueOf((externalmark*3+internalmark*1)/4);
String wgpa1=twoDForm.format(val); // gives exception
String wgpa2=twoDForm.format((externalmark*3+internalmark*1)/4)); // works fine
System.out.println(wgpa1);
The format
method takes Object type argument, so that's why I passed a String object which gives exception
该format
方法采用 Object 类型参数,这就是为什么我传递了一个给出异常的 String 对象
Exception in thread "main" java.lang.IllegalArgumentException: Cannotformat given Object as a Number.
线程“main”中的异常 java.lang.IllegalArgumentException:无法将给定的对象格式化为数字。
But when I give double value as argument the program works fine. But if the method is defined with Object
type argument why I'm getting an exception while passing a String
and not getting exception while passing double
?
但是当我给出 double 值作为参数时,程序运行良好。但是,如果该方法是使用Object
类型参数定义的,为什么我在传递 a 时String
收到异常,而在传递时却没有收到异常double
?
采纳答案by davidxxx
The format()
method of DecimalFormat
is overloaded.
的format()
方法DecimalFormat
被重载。
In the working case, you are invoking :
在工作情况下,您正在调用:
public final String format(double number)
And in the failing case, you are invoking :
在失败的情况下,您正在调用:
public final String format (Object obj)
The first method takes a very specific argument. It expects a double
.
第一种方法需要一个非常具体的参数。它期望一个double
.
This is not the case of the second one, which the type accepted is very broad : Object
and where so the check on the type passed is performed at runtime.
这不是第二个的情况,它接受的类型非常广泛:Object
因此在运行时对传递的类型进行检查。
By providing a argument that is not a double
but a String
, the method invoked is the second one.
通过提供一个不是 adouble
而是 a的参数,String
调用的方法是第二个。
Under the hood, this method relies on the format(Object number, StringBuffer toAppendTo, FieldPosition pos)
method that expects to a number
argument that is an instance of the Number
class (Short
, Long
, ... Double
):
在幕后,此方法依赖于format(Object number, StringBuffer toAppendTo, FieldPosition pos)
期望number
作为Number
类 ( Short
, Long
, ... Double
)实例的参数的方法:
@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");
}
}
But it is not the case as you passed to it a String
instance.
但事实并非如此,因为您向它传递了一个String
实例。
To solve the problem, either pass a double
primitive as in the success case or convert your String
into an instance of Number
such as Double
with Double.valueOf(yourString)
.
I advise the first way (passing a double
) as it is more natural in your code that already uses double
primitives.
The second one requires a additional conversion operation from String
to Double
.
要解决此问题,请double
在成功案例中传递一个原语,或者将您String
转换为Number
诸如Double
with的实例Double.valueOf(yourString)
。
我建议第一种方式(传递 a double
),因为它在已经使用double
原语的代码中更自然。
第二个需要从String
到的额外转换操作Double
。
回答by ajb
The answer is in the javadoc. It says clearly, "The number can be of any subclass of Number", and it says that it throws IllegalArgumentException
"if number is null or not an instance of Number."
答案在javadoc 中。它清楚地说,“数字可以是数字的任何子类”,并且它说它抛出IllegalArgumentException
“如果数字为空或不是数字的实例”。
(So why don't they just make the parameter a Number
type? Because the class is a subclass of the abstract Format
class that isn't restricted to numeric formatting. The expectation, apparently, is that while the general Format
class has a method with an Object
parameters, subclasses of Format
are expected to limit the parameters to the object types that they can handle, which they have to do at run time.)
(那么他们为什么不让参数成为一个Number
类型?因为该类是Format
不限于数字格式的抽象类的子类。显然,期望是通用Format
类有一个带有Object
参数的方法, 的子类Format
应该将参数限制为它们可以处理的对象类型,它们必须在运行时执行。)