Currently, I have three classes, Apple
, Grape
, Banana
, and I created a converter class (can convert a string to list) for each of them. Then I realized all those converter classes are basically the same except they take different class types.
The example of AppleConverter.java
public class AppleConverter extends StrutsTypeConverter {
@SuppressWarnings("rawtypes")
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
final List<Apple> appleList = new ArrayList<>();
try {
for (String appleString : values) {
Apple apple = Apple.valueOf(appleString);
appleList.add(apple);
}
}
catch (IllegalArgumentException e) {
throw new TypeConversionException(e);
}
return appleList;
}
@SuppressWarnings("rawtypes")
@Override
public String convertToString(Map context, Object o) {
if (o == null) {
return null;
}
if (o instanceof List<?>) {
List<Apple> list = (List<Apple>) o;
String appleString = list
.stream()
.map(e -> String.valueOf(e))
.collect(Collectors.joining(","));
return appleString;
}
throw new TypeConversionException("wrong");
}
Basically, GrapdeConverter.java
and BananaConverter.java
are the same as AppleConverter.java
except they take different class types.
So I tried to create a generic class then those converter classes can inherit it.
My generic class code:
public class FruitConverter<T> extends StrutsTypeConverter {
@SuppressWarnings("rawtypes")
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
if (ArrayUtils.isEmpty(values)) {
return null;
}
final List<T> objs = new ArrayList<>();
try {
for (String objStr : values) {
Object obj = toClass.getDeclaredMethod("valueOf", String.class).invoke(null, objStr);
objs.add(obj);
}
}
}
catch (IllegalArgumentException e) {
throw new TypeConversionException(e);
}
return objs;
}
@SuppressWarnings("rawtypes")
@Override
public String convertToString(Map context, Object o) {
if (o == null) {
return null;
}
if (o instanceof List<?>) {
List<?> list = (List<?>) o;
String fruitString = list
.stream()
.map(e -> String.valueOf(e))
.collect(Collectors.joining(","));
return fruitString;
}
throw new TypeConversionException("object is not a list of objs");
}
}
When I called T obj = T.valueOf(objStr);
, it throws an error can not resolve method valueOf
.
May anyone tell me how to apply generics correctly in this case.