I have a method foo
void foo (String x) { ... }
void foo (Integer x) { ... }
and I want to call it from a method which does not care about the argument:
void bar (Iterable i) {
...
for (Object x : i) foo(x); // this is the only time i is used
...
}
the code above complains that that foo(Object) is not defined and when I add
void foo (Object x) { throw new Exception; }
then bar(Iterable<String>) calls that instead of foo(String) and throws the exception.
How do I avoid having two textually identical definitions of bar(Iterable<String>) and bar(Iterable<Integer>)?
I thought I would be able to get away with something like
<T> void bar (Iterable<T> i) {
...
for (T x : i) foo(x); // this is the only time i is used
...
}
but then I get cannot find foo(T) error.
The problem you are facing is that overloaded methods are bound at compile time. In your example, the compiler tries to figure out which of the foo() methods to call. However, the strongest static type of x in your example is Object, and there is not method foo(Object), so the compiler says it can't call the appropriate method.
If you add the foo(Object) method, no matter what the actual runtime type of x is, you will always call the foo(Object) method.
This problem extends to using generics. Since T can be any type, you must have a generic method foo(T) or your code will not compile. However, if you add that method, you lose the ability to have these methods discern between the different argument types, because only foo(T) will be called.
The only way to work around this is by doing a case by case check and cast like the other answers proposed. Unless the argument types are classes you define and they can all implement a common interface. Then you can do something like:
interface ArgumentType {
void callback(FooClass c);
}
class YourClassA implements ArgumentType {
void callback( FooClass c ) {
c.foo( this );
}
}
FooClass would still have to have a foo() method for every implementing class of ArgumentType, but this way you can have your selection by type agnostic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With