@SuppressWarnings("unchecked") public static <T> T cast(Object obj, Class<T> clazz) throws Exception { if (obj == null) { return null; } TypeToken<T> type = TypeToken.of(clazz).wrap(); TypeToken<?> objType = TypeToken.of(obj.getClass()).wrap(); if (type.isAssignableFrom(objType)) { return (T) obj; } if (TypeToken.of(List.class).isAssignableFrom(type) && objType.isArray()) { List<Object> list = Arrays.asList((Object[]) obj); return (T) list; } if (type.isArray() && TypeToken.of(List.class).isAssignableFrom(objType)) { List<?> list = (List<?>) obj; TypeToken<?> componentType = type.getComponentType(); Class<?> rawType; if (componentType == null) { rawType = Object.class; } else { rawType = componentType.getRawType(); } Object[] array = (Object[]) Array.newInstance(rawType, list.size()); return (T) list.toArray(array); } if (clazz.isEnum()) { return (T) Enum.valueOf((Class<? extends Enum>) clazz, obj.toString()); } if (TypeToken.of(String.class).isAssignableFrom(type)) { return (T) obj.toString(); } if (TypeToken.of(Number.class).isAssignableFrom(type)) { BigDecimal num = new BigDecimal(obj.toString()); if (TypeToken.of(Integer.class).isAssignableFrom(type)) { return (T) Integer.valueOf(num.intValue()); } if (TypeToken.of(Long.class).isAssignableFrom(type)) { return (T) Long.valueOf(num.longValue()); } if (TypeToken.of(Short.class).isAssignableFrom(type)) { return (T) Short.valueOf(num.shortValue()); } if (TypeToken.of(Byte.class).isAssignableFrom(type)) { return (T) Byte.valueOf(num.byteValue()); } if (TypeToken.of(Float.class).isAssignableFrom(type)) { return (T) Float.valueOf(num.floatValue()); } if (TypeToken.of(Double.class).isAssignableFrom(type)) { return (T) Double.valueOf(num.doubleValue()); } } return null; }
@Override @SuppressWarnings("unchecked") public boolean isValid(Object newValue) { if (!type.isAssignableFrom(newValue.getClass())) return false; return isValidValue((T) newValue); }