Given this situation:
public class Animal {
public <T> void genericMethod(T t){
System.out.println("Inside generic method on animal with parameter " + t.toString());
}
}
public class Cat extends Animal {
public <T extends Cat> void genericMethod(T t){
System.out.println("Inside generic method on cat with parameter " + t.toString());
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Animal();
Cat cat = new Cat();
cat.genericMethod(cat);
}
}
The method genericMethod()
in class Cat
is definitely NOT overriding the superclass method (and the compiler complains if I add @Override
signature) which is reasonable, as the requirements to the type T
are different.
But I do not quite understand, how the compiler decides which of the two methods to use in the call cat.genericMethod(cat)
in the main method. Because actually both methods are visible and both are applicable. I would have expected a compiler error like "ambigous function call" here. Can someone explain this behavior?
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
Generic methods in non-generic classYes, you can define a generic method in a non-generic class in Java.
Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
From the point of view of reflection, the difference between a generic type and an ordinary type is that a generic type has associated with it a set of type parameters (if it is a generic type definition) or type arguments (if it is a constructed type). A generic method differs from an ordinary method in the same way.
These two methods have a different erasure due to the generic type bound of the sub-class method.
For the super class method the erasure is:
public void genericMethod(Object t)
For the sub class method the erasure is:
public void genericMethod(Cat t)
Method overloading resolution rules choose the method with the best matching arguments. Therefore when you pass a Cat
argument, the second (sub-class) method is chosen.
Java, at compile time, will choose the most specific matching method.
In your example, this means the Cat
implementation of the method.
THere are two things to notice:
Animal
, it is obvious that only the method declared in Animal will be used (since it doesn't match the T extends Cat
constraint).If you pass to it a Cat
:
Cat
parameter)Cat
).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