Java >> Java tutorial >  >> Tag >> throw

Formatering ved hjælp af DecimalFormat giver undtagelse - Kan ikke formatere givet objekt som et tal

format() metode til DecimalFormat er overbelastet.

I arbejdstilfældet påberåber du dig:

 public final String format(double number)

Og i det fejlslagne tilfælde påberåber du dig:

 public final String format (Object obj) 

Den første metode tager et meget specifikt argument. Den forventer en double .

Dette er ikke tilfældet med den anden, som den accepterede type er meget bred:Object og hvor så kontrollen af ​​den beståede type udføres ved kørsel.

Ved at angive et argument, der ikke er en double men en String , den påberåbte metode er den anden.

Under hætten er denne metode afhængig af format(Object number, StringBuffer toAppendTo, FieldPosition pos) metode, der forventer en number argument, der er en forekomst af Number klasse (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");
    }
}

Men det er ikke tilfældet, da du gav den en String eksempel.

For at løse problemet skal du enten sende en double primitiv som i succestilfældet eller konverter din String til en forekomst af Number såsom Double med Double.valueOf(yourString) .
Jeg anbefaler den første måde (passer en double). ), da det er mere naturligt i din kode, der allerede bruger double primitiver.
Den anden kræver en ekstra konverteringshandling fra String til Double .


Hvis der er nogen matematisk beregning, skal du bruge java.math.BigDecimal klasses metoder er det bedre valg for nøjagtighed i resultater og effektive i ydeevne, lige tal er for store.Brug af java.math.BigDecimal-kode :

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());

Java tag