@@ -19,7 +19,7 @@ public class StringToNumberConverter extends AbstractConverter<String, Number> {
1919 @ SuppressWarnings ("unchecked" )
2020 public <T > T convert (Object src , Class <T > dest ) {
2121 // ensure type is well-behaved, rather than a primitive type
22- Class <T > saneDest = Types . box (dest );
22+ Class <T > saneDest = sane (dest );
2323 if (!(src instanceof String )) throw new IllegalArgumentException (
2424 "Expected src to be a String but got a " + src .getClass ());
2525 if (!(Number .class .isAssignableFrom (saneDest )))
@@ -33,7 +33,6 @@ public <T> T convert(Object src, Class<T> dest) {
3333 if (saneDest == Long .class ) return (T ) new Long (srcString );
3434 if (saneDest == Float .class ) return (T ) new Float (srcString );
3535 if (saneDest == Double .class ) return (T ) new Double (srcString );
36- if (saneDest == Number .class ) return (T ) new Double (srcString );
3736 else throw new IllegalArgumentException ("Unknown destination type: " +
3837 saneDest );
3938 }
@@ -51,6 +50,22 @@ public Class<String> getInputType() {
5150 @ Override
5251 public boolean canConvert (Object src , Class <?> dest ) {
5352 if (!Types .isAssignable (src .getClass (), String .class )) return false ;
54- return Types .isAssignable (Types .box (dest ), Number .class );
53+ // The only way to know if the conversion is valid is to actually do it.
54+ try {
55+ String srcString = (String ) src ;
56+ sane (dest ).getConstructor (String .class ).newInstance (srcString );
57+ return true ;
58+ }
59+ catch (Exception e ) {
60+ return false ;
61+ }
62+ }
63+
64+ // -- Helper functionality -- //
65+
66+ @ SuppressWarnings ("unchecked" )
67+ private <T > Class <T > sane (Class <T > c ) {
68+ if (c == Number .class ) return (Class <T >) Double .class ;
69+ return Types .box (c );
5570 }
5671}
0 commit comments