I would not have problems with IF
s for a specific system routine with a very limited scope. It would be the cleanest and most efficient way.
But if the idea is to temper your system with some of the magic that frameworks generally use so much, I would take a different approach. In fact it's not that different because it's ultimately based on a map, as some answers have already done so.
However, the fundamental difference lies in the treatment of the generic value you want to put in and take out of an HTML field. It is not enough to recover and know the type of data, it is necessary to act upon it. If we just put the type on a map and recover it, we'll still end up with% s of% s.
A worse situation is when the various developers begin to add different and custom types to the beans. Will every time a new need arise you will need to tinker with this code? Do not want this headache!
One approach would be to use the converters concept, such as JSF, JPA, and other APIs that already have this kind of feature.
Are we reinventing the wheel? Yes! But it's worth it, even for learning!
Defining a Converter
Let's define a converter that is able to place and retrieve values from HTML fields. All we need is to convert a value from a qualuqer type to String and String to the type again, ie, go round and round to an HTML field.
public interface Converter<T> {
String toString(Object value);
T fromString(String str);
}
Implementing basic Converters
IF
public class StringConverter implements Converter<String> {
@Override
public String toString(Object value) {
return value.toString();
}
@Override
public String fromString(String str) {
return str;
}
}
String
public class IntegerConverter implements Converter<Integer> {
@Override
public String toString(Object value) {
return value.toString();
}
@Override
public Integer fromString(String str) {
return Integer.parseInt(str);
}
}
Integer
public class DateConverter implements Converter<Date> {
@Override
public String toString(Object value) {
return new SimpleDateFormat("dd/MM/yyyy").format(value);
}
@Override
public Date fromString(String str) {
try {
return new SimpleDateFormat("dd/MM/yyyy").parse(str);
} catch (ParseException e) {
throw new IllegalArgumentException("Data inválida: '" + str + "'!");
}
}
}
Managing Converters
Now that we have some converters, let's create a class to manage all of that.
public class ConverterManager {
private static Map<Class<?>, Converter<?>> converterMap = new HashMap<Class<?>, Converter<?>>();
static {
//default converters
converterMap.put(String.class, new StringConverter());
converterMap.put(Integer.class, new IntegerConverter());
converterMap.put(Date.class, new DateConverter());
}
/**
* Recupera um conversor de um tipo específico
* @param classe Tipo do conversor
* @return Instância do conversor
*/
@SuppressWarnings("unchecked")
public static <T> Converter<T> getConverter(Class<T> classe) {
return (Converter<T>) converterMap.get(classe);
}
/**
* Permite o registro de um novo conversor
* @param classe Tipo do conversor
* @param converter Instância do conversor
*/
public static <T> void registerNewConverter(Class<T> classe, Converter<T> converter) {
converterMap.put(classe, converter);
}
}
The java.util.Date
class initializes some standard converters and allows the developer to register new converters for the types you want.
Example usage
A simple example of how a round-trip code gets:
//um valor qualquer
Object val1 = 1;
//recupera o converter
Converter<?> converter = ConverterManager.getConverter(val1.getClass());
//converter para String
String str1 = converter.toString(val1);
//converte novamente para inteiro
Integer int1 = (Integer) converter.fromString(str1);
The difference of this basic example is that in your case you will need to use reflection to execute the getter and setter methods or directly access Field in question.
I think using attributes rather than methods is better, because the code gets more efficient and clean. However, this can cause problems if there is any logic in the methods that is important.