joyidahosa
joyidahosa

Reputation: 23

How do I create a method that takes generics as parameter and calls methods from them?

I have a mixin that I would like to use for several types of requests, e.g. CatRequest and DogRequest. I created a method in the mixin that retrieves certain details from the request, depending on the type of request and sets in the response. Would it be ideal to check for instances and cast them like below or is there a better way to use generics to handle this?

default <T> Response setAnimalDetails(final T request, final Response response) {
    Animal animal = new Animal();
    if (request instanceof CatRequest) {
        CatRequest catRequest = (CatRequest) request;
        animal.setType(catRequest.getType());
        animal.setAge(catRequest.getAge());
        animal.setWhiskerLength(catRequest.getWhiskerLength());
    } else if (request instanceof DogRequest) {
        DogRequest dogRequest = (DogRequest) request;
        animal.setType(dogRequest.getAnimalType());
        animal.setAge(dogRequest.getAge());
        // since dogs don't have whiskers, DogRequest doesn't have a whiskers field
    }
    response.setAnimal(animal);
    return response;
}

Upvotes: 0

Views: 49

Answers (1)

Leo Aso
Leo Aso

Reputation: 12463

Mixins and generics seem like a roundabout way to achieve something you could just do via inheritance.

interface AnimalMaker {
    Animal createAnimal();
}

class CatRequest implements AnimalMaker {
    @Override 
    public Animal createAnimal() {
        Animal animal = new Animal();
        animal.setType(getType());
        animal.setAge(getAge());
        animal.setWhiskerLength(getWhiskerLength());
        return animal;
    }
}

class DogRequest implements AnimalMaker {
    @Override 
    public Animal createAnimal() {
        Animal animal = new Animal();
        animal.setType(getAnimalType());
        animal.setAge(getAge());
        return animal;
    }
}

This way, instead of needing that setAnimalDetails method, you can simply declare your request as an AnimalMaker and do

response.setAnimal(request.createAnimal());

It would be even better to make subclasses of Animal like Cat and Dog, and make them type parameters for the request classes, but that you can do on your own.

Upvotes: 1

Related Questions