Dynamic Class to a Variable in Java : Converting JSON to Object based on type of JSON

Viewed 71

I have different types of fields for an object which is stored as JSONB in the Database Table. I can load the whole table into an Object and need to convert them to POJO Objects.

My JSON to POJO method is

  public static <T> T fromJson(String json, Class<T> clazz) {
    try {
      return OBJECT_MAPPER.readValue(json, clazz);
    } catch (JsonProcessingException ex) {
      throw new BadJsonException(ex);
    }
  }

Since I need to pass in the class, I am trying to write an elegant maintainable way to do this. So, if I need to compare two values this works

  public static Integer compareFieldValue(
    String valueA,
    String valueB,
    ProjectFieldType fieldType
  ) {
    FieldValue objA;
    FieldValue objB;

    switch (fieldType) {
      case CURRENCY:
        objA = JsonHelper.fromJson(valueA, CurrencyField.class);
        objB = JsonHelper.fromJson(valueB, CurrencyField.class);

        break;
      case DATETIME:
        objA = JsonHelper.fromJson(valueA, DateTimeField.class);
        objB = JsonHelper.fromJson(valueB, DateTimeField.class);
        break;

But a long Switch Case Statement doesn't look good. I am trying to have it in an Enum and return it but then I am getting Incompatible Types error

ProjectFieldType.java:[25,44] incompatible types: java.lang.Class<com.foo.model.projectfield.DateTimeField> cannot be converted to java.lang.Class<com.foo.model.projectfield.FieldValue>

In the enum the field class is defined as

  private final Class<FieldValue> fieldClazz;

Every Enum value would have a Field Type associated with it. DateTimeField implements FieldValue interface.

Not sure how to go about it. Java is not my first Language, Python is. So, its kinda confusing to me to figure out best ways to do these kinda things in Java World.

Thanks for the help -Shaurya

1 Answers
ProjectFieldType.java:[25,44] incompatible types: java.lang.Class<com.foo.model.projectfield.DateTimeField> cannot be converted to java.lang.Class<com.foo.model.projectfield.FieldValue>

This just means that DateTimeField cannot be converted to FieldValue, because DateTimeField objects are not an instanceof FieldValue.

This method can be simplified by far. The approach is fine, but instead of passing an enum, you can pass in the class directly as below.

Make sure all the classes you are comparing implements Comparable Interface so that compareTo() method is overridden.

public static <T extends Comparable<T>> Integer convert(String a, String b,Class<T> co) {
    T obj1 = JsonHelper.fromJson(a, co);
    T obj2 = JsonHelper.fromJson(b, co);
    return obj1.compareTo(obj2);
}

This can be invoked as

convert("Hello", "Anees",String.class);

String.class is taken as an example because it implements Comparable<String>

Related