2017-07-24 24 views
0

这可能看起来像一个重复的问题,但我尝试在所有下面的链接,并不能得到正确的答案。使用DecimalFormat格式异常 - “无法格式化给定的对象作为数字”

Cannot format given Object as a Number ComboBox

Illegal Argument Exception

但我没有收到什么是错。这里是我的代码

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方法将Object类型作为参数,所以这就是为什么我通过一个String对象,那个时候它给例外Exception in thread "main" java.lang.IllegalArgumentException: Cannot format given Object as a Number

但是,当我给双值作为参数程序工作正常。但是,如果方法是用Object类型参数定义的,为什么我在传递String时遇到异常,而在传递double时没有得到异常? PS:我们使用的是JDK 6.0。

回答

3

DecimalFormatformat()方法过载。

在工作情况下,要调用:

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类的实例(ShortLong,... 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原始作为成功案例或将您的StringNumberDouble一个实例与Double.valueOf(yourString)
我建议第一种方法(通过double),因为在您的代码中已经使用double原语更自然。
第二个需要从StringDouble的额外转换操作。

1

答案在javadoc。它清楚地表明,“该号码可以是任何数字的子类别”,并且它表示如果号码为空或不是数字的实例,则它会抛出IllegalArgumentException。“

(那么,为什么不干脆让参数Number类型?因为类是不局限于数字格式的抽象Format类的子类。人们期望,显然的是,虽然一般Format类具有带有Object参数的方法中,子类Format预期限制参数的对象类型,他们能够处理,它们在运行时执行。)