Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic method not overriding similar generic method in superclass -> Which one is used?

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?

like image 885
DanielBK Avatar asked Feb 08 '18 07:02

DanielBK


People also ask

What are generic methods generic methods are the methods defined in a generic class?

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.

Can you have a generic method in a non-generic class?

Generic methods in non-generic classYes, you can define a generic method in a non-generic class in Java.

What is generic method how it is useful?

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.

How does generic method differ from generic type explain with an example?

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.


2 Answers

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.

like image 88
Eran Avatar answered Sep 17 '22 07:09

Eran


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:

  • If you pass to it an 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:

    1. Java decides that the two methods match (because of the Cat parameter)
    2. Because of the aforementioned rule, Java simply take the most specific one (it does not care anymore about the fact that the parameter is a Cat).
like image 34
Victor Noël Avatar answered Sep 20 '22 07:09

Victor Noël