这可能看起来像是一个重复的问题,但我尝试了以下所有链接,但无法得到正确答案。
Cannot format given Object as a Number ComboBox
但我没有弄错。这是我的代码
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);
format
方法采用对象类型参数,这就是为什么我传递给出异常的String对象
线程中的异常" main" java.lang.IllegalArgumentException:不能 将对象格式化为数字。
但是当我将double值作为参数时,程序运行正常。但是,如果使用Object
类型参数定义方法,为什么我在传递String
时遇到异常而在传递double
时没有获得异常?
答案 0 :(得分:11)
format()
的{{1}}方法已超载。
在工作案例中,您正在调用:
DecimalFormat
在失败的情况下,你正在调用:
public final String format(double number)
第一种方法需要一个非常具体的参数。它需要 public final String format (Object obj)
。
第二种情况并非如此,接受的类型非常宽泛:double
所以对传递类型的检查是在运行时执行的。
通过提供不是Object
而是double
的参数,调用的方法是第二个。
在幕后,此方法依赖于期望String
参数的format(Object number, StringBuffer toAppendTo, FieldPosition pos)
方法,该参数是number
类的实例(Number
,{{1 },... 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");
}
}
原语,或将String
转换为double
的实例,例如String
{{1} }}。
我建议采用第一种方式(传递Number
),因为在您的代码中使用Double
原语更为自然。
第二个需要从Double.valueOf(yourString)
到double
进行额外的转换操作。
答案 1 :(得分:2)
如果有任何数学计算,则使用 java.math.BigDecimal 类的方法是更好的选择,即使结果太大也可以提高结果的准确性和性能。 使用java.math.BigDecimal代码:
double externalmark1 = 1.86;
double internalmark2 = 4.0;
System.out.println(String.valueOf((externalmark1*3+internalmark2*1)/4));
System.out.println("------------------------");
BigDecimal decimalValue1 = new BigDecimal((externalmark1*3+internalmark2*1)/4).setScale(2, RoundingMode.HALF_UP);
System.out.println("aggregatemark [direct decimalValue]: "+decimalValue1.toString());
System.out.println("------------------------");
double aggregatemark = (externalmark1*3+internalmark2*1)/4;
System.out.println("aggregatemark [double]: "+aggregatemark);
BigDecimal decimalValue2 = new BigDecimal(aggregatemark).setScale(2, RoundingMode.HALF_UP);
System.out.println("aggregatemark [decimalValue]: "+decimalValue2.toString());
System.out.println("------------------------");
String aggregatemarkStr = String.valueOf((externalmark1*3+internalmark2*1)/4);
System.out.println("aggregatemark [string] : "+aggregatemarkStr);
BigDecimal decimalValue3 = new BigDecimal(aggregatemarkStr).setScale(2, RoundingMode.HALF_UP);
System.out.println("aggregatemark [decimalValue]: "+decimalValue3.toString());
答案 2 :(得分:1)