Примерно так:
private static final Map<Class<?>, Class<?>> primitiveToBoxed = new HashMap<>();
static {
primitiveToBoxed.put(Boolean.TYPE, Boolean.class);
primitiveToBoxed.put(Character.TYPE, Character.class);
primitiveToBoxed.put(Byte.TYPE, Byte.class);
primitiveToBoxed.put(Short.TYPE, Short.class);
primitiveToBoxed.put(Integer.TYPE, Integer.class);
primitiveToBoxed.put(Long.TYPE, Long.class);
primitiveToBoxed.put(Float.TYPE, Float.class);
primitiveToBoxed.put(Double.TYPE, Double.class);
primitiveToBoxed.put(Void.TYPE, Void.class);
}
private static final Map<Class<?>, Set<Class<?>>> allowedConversions = new HashMap<>();
static {
allowedConversions.put(Short.class, setOf(Byte.class));
allowedConversions.put(Integer.class, setOf(Byte.class, Character.class, Short.class));
allowedConversions.put(Long.class, setOf(Byte.class, Character.class, Short.class, Integer.class));
allowedConversions.put(Float.class, setOf(Byte.class, Character.class, Short.class, Integer.class, Long.class));
allowedConversions.put(Double.class, setOf(Byte.class, Character.class, Short.class, Integer.class, Long.class, Float.class));
}
static <T> Set<T> setOf(T... elements) {
return new HashSet<>(Arrays.asList(elements));
}
static boolean isCompatible(Class<?> type, Object value) {
if (type.isPrimitive()) {
if (value == null) {
return false;
}
type = primitiveToBoxed.get(type);
}
return value == null || type.isAssignableFrom(value.getClass())
|| allowedConversions.getOrDefault(type, emptySet()).contains(value.getClass());
}