org.apache.wicket.util.lang.PropertyResolverConverter Type Erasure leads to Sloppy Typing -----------------------------------------------------------------------------------------
Key: WICKET-3441 URL: https://issues.apache.org/jira/browse/WICKET-3441 Project: Wicket Issue Type: Bug Components: wicket Affects Versions: 1.5-RC1 Environment: all Reporter: Richard Emberson Priority: Minor There seems to be some problems with the org.apache.wicket.util.lang.PropertyResolverConverter convert method that the Java compiler lets slip because of type erasure. To show this, lets let the convert method had type parameterized arguments: public <OT, CT> Object convert(OT object, Class<CT> clz) and the converter is then typed: IConverter<CT> converter = converterSupplier.getConverter(clz); then the block of code: else if (clz == String.class) { return converter.convertToString(object, locale); } has an issue because the convertToString expects object to have type CT. Because of type erasure, the Java compiler lets this slip by. In addition, since the class type is String, the converter used is just the ConverterLocator,DefaultConverter whose convertToString method ends up calling return (String)Objects.convertValue(value, String.class); which, when nothing can be found to convert to a "known" value simply returns the value parameter. Again, all this is allowed because the Java compiler gets sloppy due to type erasure. But calling Objects.convertValue is just what the block of code following the above convert method code does: else { try { return Objects.convertValue(object, clz); } catch (RuntimeException ex) { // ignore that try it the other way } // go through string to convert to the right object. String tmp = converter.convertToString(object, locale); return converter.convertToObject(tmp, locale); } So, the previous block of code: else if (clz == String.class) { return converter.convertToString(object, locale); } can be removed 1) allowing for correct typing and 2) with the same results. Also, if one examines the code: // go through string to convert to the right object. String tmp = converter.convertToString(object, locale); return converter.convertToObject(tmp, locale); one sees that this has the same sloppy typing as the code block just remove, that is: return converter.convertToString(object, locale); Again, object is of type OT while the convertToString method of the IConverter is expecting a type of CT. The fix is to use an IConverter of the type of OT to convert to String and then the IConverter of type CT to convert to the return object: // go through string to convert to the right object. IConverter<OT> converterForObj = converterSupplier.getConverter(object.getClass()); String tmp = converterForObj.convertToString(object, locale); return converter.convertToObject(tmp, locale); This is now correctly typed. I noticed this because there is rather more theory behind Scala's type system than Java's so that the Scala compiler complained about the attempt to sneak around the type erasure. -- This message is automatically generated by JIRA. - For more information on JIRA, see: http://www.atlassian.com/software/jira