2

There are two entities classes:

public class Base {
    private String provider;
}

public class SuperClass extends Base {
    private String trunk;
}

and main class:

public class Test {
    public static <T extends Base> List<T> getDetailedReport(Class<T> clazz, String providerName) {
        List<T> list = new ArrayList<>();
        T entity = new Base(); // this is wrong, of course.
        return list;
    }

    public static void main(String[] args) {
        Base base = new Base();
        ​SuperClass superClass = new SuperClass();
        List<Base> baseList = getDetailedReport(Base.class, "Telia");
        List<SuperClass> superClassList = getDetailedReport(SuperClass.class, "Globalcom");
    ​}
​}

I'm trying to create generic method getDetailedReport which returns list of entities. Type of entity is passed through clazz variable. My question is: How to create entity of necessary type?

3
  • Duplicate? stackoverflow.com/questions/75175/… Commented May 27, 2021 at 8:08
  • You could use reflection, i.e. the newInstance() method on Class or one of the constructors. However, you seem to need parameters (like provider for both and trunk for SuperClass) so some kind of factory might be better suited here. Commented May 27, 2021 at 8:09
  • stackoverflow.com/questions/67529555/… Commented May 27, 2021 at 8:13

1 Answer 1

0

Reflection API is your friend here. To use the following implementation, you need to make sure the following conditions:

  1. The Base and all the derived objects have no-args constructor (i.e. new Base() or new SuperClass()).
  2. You need deal with 4 thrown exceptions: NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException.

Minimal sample (using Lombok):

@Data
@NoArgsConstructor
public static class Base {
    private String provider;
}
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@NoArgsConstructor
public static class SuperClass extends Base {
    private String trunk;
}
@SneakyThrows
static <T extends Base> List<T> getDetailedReport(Class<T> clazz, String provider) {
    List<T> list = new ArrayList<>();
    T entity = clazz.getDeclaredConstructor().newInstance();
    entity.setProvider(provider);
    list.add(entity);
    return list;
}
List<Base> baseList = getDetailedReport(Base.class, "Telia");
List<SuperClass> superClassList = getDetailedReport(SuperClass.class, "Globalcom");

System.out.println(baseList);
// [Main.Base(provider=Telia)]

System.out.println(superClassList); 
// [Main.SuperClass(super=Main.Base(provider=Globalcom), trunk=null)]
  • I made the data classes static in order to use in the class with the main method comfortably
  • I used @SneakyThrows for safe of answer clarity - you, however, need to handle these exceptions
  • Note that @NoArgsConstructor satisfies clazz.getDeclaredConstructor().newInstance().
  • You might need to modify the implementation as you need (I let the method pass String provider into a newly created instance through the Reflection API and returned it in the List as a demonstration).
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.