The general Java method. Why is T displayed as Map?

Consider the following code

class MyClass { public MyClass(Map<String, String> m) { System.out.println("map"); } public MyClass(SortedMap<String, String> m) { System.out.println("sortedmap"); } } public class Test { public <T extends Map<String,String>> Test(T t) { new MyClass(t); } public static void main(String[] args) { new Test(new TreeMap<String,String>()); } } 

He prints a map . Why SortedMap T display map instead of SortedMap in public <T extends Map<String, String>> Test(T t) ? Is there a way to change this behavior to use the most specific constructor for MyClass ?

+6
source share
1 answer

Called which constructor MyClass is called, is executed at compile time. When the compiler compiles the code of the Test constructor, he does not know what T , he just knows that Map<String, String> guaranteed to be, so he can do nothing but bind the constructor invocation to the constructor that accepts Map . The knowledge that there is a TreeMap in your T code is present only inside the body of the main method, and not outside. For example, consider what happens if you add a second caller to the Test constructor, which actually passes the HashMap .

Java generics work so that the code of the universal method is compiled only once for all possible common parameter values ​​(and only once in byte code), in other languages ​​there is no copy of the common method for each common type.

In general, in Java, it is not possible for a single method / constructor call in the code to actually call different methods / constructors at run time, depending on the type of arguments. This is possible only for method calls depending on the type of runtime of the called object (dynamic binding to rewritten methods).

Overloading (what you are here) only works at compile time, considering the static type of arguments.

A typical solution for this situation would be to use the instanceof SortedMap inside the MyClass constructor. Another possible (more elegant) solution is the visitor template, but this only works with classes prepared for it (and not with Map instances unless you wrap them in your own class).

+4
source

Source: https://habr.com/ru/post/981149/


All Articles