Cela pourrait ressembler à une question répétée, mais j'ai essayé tous les liens ci-dessous et je ne peux pas obtenir une réponse correcte.
Impossible de formater un objet donné sous forme de zone de liste déroulante numérique
Mais je ne me trompe pas. Voici mon 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);
La méthode format
prend l'argument de type Object, c'est pourquoi j'ai passé un objet String qui donne une exception
Exception dans le thread "principal" Java.lang.IllegalArgumentException: Impossible de formater l'objet donné sous forme de nombre.
Mais quand je donne une valeur double comme argument, le programme fonctionne bien. Mais si la méthode est définie avec l'argument de type Object
pourquoi j'obtiens une exception en passant un String
et que je n'obtiens pas d'exception en passant double
?
La méthode format()
de DecimalFormat
est surchargée.
Dans le cas de travail, vous invoquez:
public final String format(double number)
Et dans le cas contraire, vous invoquez:
public final String format (Object obj)
La première méthode prend un argument très spécifique. Il attend un double
.
Ce n'est pas le cas du second, dont le type accepté est très large: Object
et où donc la vérification du type passé est effectuée lors de l'exécution.
En fournissant un argument qui n'est pas un double
mais un String
, la méthode invoquée est la deuxième.
Sous le capot, cette méthode repose sur la méthode format(Object number, StringBuffer toAppendTo, FieldPosition pos)
qui attend un argument number
qui est une instance de la classe 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");
}
}
Mais ce n'est pas le cas puisque vous lui avez passé une instance String
.
Pour résoudre le problème, passez une primitive double
comme dans le cas de réussite ou convertissez votre String
en une instance de Number
telle que Double
avec Double.valueOf(yourString)
.
Je conseille la première façon (en passant un double
) car c'est plus naturel dans votre code qui utilise déjà les primitives double
.
La seconde nécessite une opération de conversion supplémentaire de String
vers Double
.
La réponse est dans le javadoc . Il dit clairement, "Le nombre peut être de n'importe quelle sous-classe de Nombre", et il dit qu'il jette IllegalArgumentException
"si nombre est nul ou non une instance de Nombre."
(Alors pourquoi ne font-ils pas simplement du paramètre un type Number
? Parce que la classe est une sous-classe de l'abstrait Format
classe qui n'est pas limitée au numérique Apparemment, on s'attend à ce que, bien que la classe générale Format
ait une méthode avec des paramètres Object
, des sous-classes de Format
devraient limiter les paramètres aux types d'objet qu'ils peuvent gérer, ce qu'ils doivent faire au moment de l'exécution.)