I’m working on a settings screen (using JSP) which iterates over a Map of generic SettingEntries. A SettingEntry is defined as follows:
public class SettingEntry <T> implements Serializable {
private final String key;
private final T defaultValue;
private T value;
// Ctor, getters and setters removed for brevity's sake
}/code>
When a user enters a new value, ideally the form value should be converted to the correct type. For example, “board.size†was created as a SettingEntry <Integer>. Ideally XWork/WebWork's type conversion should set the value as a new Integer. However, this is not the case. Instead, a String[] array (WW's default type for form parameters), of length one is set as the value.
Java's implementation of generics does not create a new class based on a class template. Instances of a generic class have the same run-time class. So, the following lines will both print true:
System.out.println(new HashSet<String>().getClass() == new HashSet<String>().getClass());
System.out.println(new HashSet<String>().getClass() == new HashSet<Integer>().getClass());
Well, after looking through a piece by Gilad Bracha, I made SettingEntry<T> aware of its type, in a generic way. I added a generic instance of the targetClass to SettingEntry, and then I could at least check that the T value being set on the SettingEntry instance is the same Class that the class was initially made with. Now, I can just make a converter which will create new instances based on the targetClass.
Currently, XWork-Tiger allows for a collection’s generic type to be used, rather than the developer defining the element types, and the key for maps in a conversion property file. Although this is a specific use case (iterating over a map of generic settings), I think the new XWork-Tiger module could benefit from this. It should allow for users to define a target Class, which XWork could later use to provide new instances, or at least properly cast existing references.