Reputation: 7719
I have the following methods in one class:
void delete(ClassA a) {
//....
}
void delete(ClassB b) {
//...
}
void delete(List<ClassA> list) {
for (ClassA a: list) {
delete(a);
}
}
void delete(List<ClassB> list) {
for (ClassB b: list){
delete(b);
}
}
The overloading works fine for the first two methods. But there's a conflict between third and fourth methods.
Is it possible to replace them with one method? I tried the following method, which is not correct:
void delete(List<? extends Object> list){
for (Object o: list){
delete((o.getClass())o);
}
}
How can I detect the class type of the instance in list at runtime and call the appropriate method?
Upvotes: 3
Views: 2591
Reputation: 7290
You tried to have different implementations for the deletion of a List<ClassA>
vs. List<ClassB>
. You can do that in Java, but not with the same method name.
So, you can have one deleteAList(List<ClassA> aList)
and one deleteBList(List<ClassB> bList)
.
Technically, overloading means that different methods share the same base name, but have different parameter types, so the compiler knows which method to call.
Or to put it another way, the effective method name is composed from the name you created plus the parameter types. And that concept was defined before the introduction of generics, so it just sees delete(List list)
, ignoring the generics type parameter that you added to the List
. So you have two methods of the same effective method name, and that's what the compiler complains about.
So, help the compiler by making the method base names different, and everything is OK.
Upvotes: 1
Reputation: 393771
Overloading is resolved at compile time, so you can't rely on the runtime types.
What you can do is check the runtime types with instanceof
and cast to the relevant type explicitly:
void delete(List<? extends Object> list){
for (Object o: list) {
if (o instanceof ClassA) {
delete((ClassA) o);
} else if (o instanceof ClassB) {
delete((ClassB) o);
}
}
}
Upvotes: 3