Reputation: 9932
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
Reputation: 35096
This isn't proper use of generics. You should use method overloading instead
Upvotes: 0
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