How to return different types from mapper method in Java?

Viewed 119

How can I return different types in one method and make set operations above them? For example, I have a few similar classes: AddDeveloperResponse, EditDeveloperResponse, DeleteDeleveloperResponse

In general, I had 3 methods, where I return these different classes, but I think it can make this stuff in a single method

They contain the same fields:

@Getter
@Setter
@ToString
@EqualsAndHashCode
public class DeleteDeveloperResponse extends DeveloperResponseBaseEntity<DeleteDeveloperResponse >{
   private long id;
   private BigDecimal salary;
   private String message;
}

I created a basic class, but I don't know how to connect them correctly:

@Getter
@Setter
public abstract class DeveloperResponseBaseEntity<T> {
   private long id;
   private BigDecimal salary;
   private String message;
}

Here is my method, this should look like:

public <T extends > T getDeveloperResponseFromDeveloper(Developer developer) {
    T response = new T(); //but we can't create object of Generic 
    // OR T response = new DeveloperResponseBaseEntity<T>;
    response.setId(developer.getd());
    //other set operations
    return response;
}

And I want to invoke this method with different classes, for example:

AddDeveloperResponse addDevResponse = userMapper.getDeveloperResponseFromDeveloper(Developer);
EditDeveloperResponse editDevResponse = userMapper.getDeveloperResponseFromDeveloper(Developer);
//OR
EditDeveloperResponse editDevResponse = userMapper.<EditDeveloperResponse>getDeveloperResponseFromDeveloper(Developer);

If you can, just explain to me how it should work generally in java

If you know related topics, send them in comments, I will be grateful for any help

1 Answers

You could maybe use something like this:

public <T extends DeveloperResponseBaseEntity<T>> T getDeveloperResponseFromDeveloper(Developer developer, Supplier<? extends T> responseConstructor) {
    T response = responseConstructor.get();
    response.setId(developer.getId());
    // other set operations
    return response;
}

And then call it like this, assuming AddDeveloperResponse has a no arg constructor:

AddDeveloperResponse addDevResponse = userMapper.getDeveloperResponseFromDeveloper(Developer, AddDeveloperResponse::new);

As you probably know, you can't instantiate a generic type directly, so you need to help java a bit. I did this with Supplier<? extends T> responseConstructor where you can pass the constructor of the type you want to instantiate. You could also pass an instance directly, i.e. replace the Supplier responseConstructor with T response directly.

Related