Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics: Make sure parameters are of same type

I've got the following method:

protected <S> void setValue(final S oldValue, final S newValue) {
    // Do something
}

I want to make sure, that both parameters are of the same type. It would be cool, if there'd be a compiler error when you try to pass parameters of two different types.

The above way is clearly not the correct one. I can put into a String and an Integer, since the both extend from Object.

Is my want even possible? Or is the only way to make sure both parameters are of the same type to check it inside the method and throw an IllegalArgumentException?


2 Answers

You can do that if you consider that S is the correct type :

protected <S, T extends S> void setValue(final S oldValue, final T newValue) {
    // Do something
}

You can and can't input these :

// Works
setValue("something", "something");
setValue(new Object(), new String());

// Doesn't work
setValue(new String(), new Object());

or

You can do :

protected <S> void setValue(final S oldValue, final S newValue, final Class<S> clazz) {
    // Do something
}

and use it like that

setValue("something", "something", String.class);

or

protected <S> void setValue(final S oldValue, final S newValue) {
    if(!oldValue.getClass().equals(newValue.getClass())) {
        //throw something
    }
}
like image 70
Simon LG Avatar answered Oct 14 '25 15:10

Simon LG


This isn't really possible, I'm afraid, except for explicit checks. It'll always get coerced up to Object; there's no way to stop inputs from getting coerced up to supertypes.

You can use explicit reflection-based checking in your argument validation, but that's just about your only option.

like image 24
Louis Wasserman Avatar answered Oct 14 '25 14:10

Louis Wasserman