Search code examples
javagenericsconstructorinstantiationdto

Java: Instantiate generic object with non-default constructor


in the project I´m working on, I have to create several times, different objects from their DTO. Trying to follow the principle of not repeating code, I tried to create a general class like this:

public class AssembleObjectFromDto<T,Tdto> {
    public List<T> tFromDto(List<Tdto> tdtoList){
        List<T> tList = new ArrayList<>();
        for(Tdto tdto : tdtoList){
            tList.add(new T(tdto));
        }
        return tList;
    }
}

but, I can not instantiate a generic object directly.

I wanted to know, what other approach can I use to solve this problem.

Thanks in advance


Solution

  • You can't do that, because neither the compiler nor the runtime can't know the concrete type of T and Tdto, and thus can't even know if such a constructor exist.

    But you can pass a Function<Tdto, T> instead:

    public List<T> tFromDto(List<Tdto> tdtoList, Function<Tdto, T> constructor){
        List<T> tList = new ArrayList<>();
        for(Tdto tdto : tdtoList){
            tList.add(constructor.apply(tdto));
        }
        return tList;
    }
    

    That you would call, the following way:

    List<Foo> dtos = assemble.tFromDto(fooDTOs, Foo::new)
    

    Note that this method doesn't need to be in a generic class. It could be generic and could be static (and simplified using streams):

    public static <T, D> List<T> fromDTOs(List<D> dtoList, Function<D, T> constructor){
        return dtoList.stream().map(constructor).collect(Collectors.toList());
    }
    

    Given the simplicity of this method, you could even remove it completely.