Feuermurmel
Feuermurmel

Reputation: 9932

Handle specific types in a generic method takes and returns the same generic type

I have a generic method T foo(T) which, depending on the actual type of the argument, performs different operations. Following is an example that illustrates the same problem. (See below for a description of what I'm actually doing in my code.)

<T extends Number> T foo(T a) {
    if (a instanceof Integer) {
        return ((Integer) a) + 1;
    } else if (a instanceof Double) {
        return ((Double) a) + 1;
    } else {
        throw new IllegalArgumentException();
    }
}

This does not violate the requirement of the return type but it is not accepted by javac. The problem is that e.g. the return ((Integer) a) + 1; will only ever be executed when T is Integer but the compiler can't (according to the JLS) infer this and thus expects that a T is passed to return. The expression there is typed as int, which can't be converted to T.

Is there a way to deal with this situation without resorting to an unchecked cast?


What I'm actually doing in my code: In the application, there's a generic interface which is used to encapsulate some value. There are different specialized implementations of that interface for different value types and the method I'm trying to write should dynamically chose the right implementation.

Upvotes: 0

Views: 56

Answers (2)

ControlAltDel
ControlAltDel

Reputation: 35096

This isn't proper use of generics. You should use method overloading instead

Upvotes: 0

rgettman
rgettman

Reputation: 178303

If you are type-checking a at runtime, then you are defeating the point of generics. But generics don't work with mathematical operators anyway, because those operators work with primitives and type parameters work with reference types. Your workaround doesn't work with the compiler because T could be any Number type at compile time, so the compiler can't allow you to return an Integer when it thinks it could be any Number type.

Instead, I would overload two non-generic foo methods -- one with int and one with double. Neither of these methods would be generic, and each would just perform its own operation.

Upvotes: 3

Related Questions