Есть код: ВНИМАНИЕ, ГОТОВОЕ РЕШЕНИЕ!!!
public interface Convertable<Key> {
    Key getKey();
}

public class ConvertableUser implements Convertable<Integer> {
    private Integer id;
    private String name;

    public ConvertableUser(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public Integer getKey() {
        return id;
    }

    @Override
    public String toString() {
        return "ConvertableUser{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

public class Solution {
    public static void main(String[] args) {
        List<ConvertableUser> users = new ArrayList<>();
        users.add(new ConvertableUser(234, "First User"));
        users.add(new ConvertableUser(235, "Second User"));
        users.add(new ConvertableUser(236, "Third User"));

        Map<Integer, ConvertableUser> newMap = ConvertableUtil.convert(users);
        System.out.println(newMap);
        //{236=ConvertableUser{id=236, name='Third User'},
        // 235=ConvertableUser{id=235, name='Second User'},
        // 234=ConvertableUser{id=234, name='First User'}}
    }
}

public class ConvertableUtil {
    public static <K, V extends Convertable<K>> Map<K, V> convert(List<V> list) {
        Map<K, V> result = new HashMap<>();

        for (V value : list) {
            result.put(value.getKey(), value);
        }

        return result;
    }
}
Меня интересует как на самом деле работает эта строка в методе main:
Map<Integer, ConvertableUser> newMap = ConvertableUtil.convert(users);
Как бы метод convert имеет дженерики, но вообще нигде при его вызове не передаються ни какие типы ввиде параметров (в треугольных скобках "< >"). Вроде как вызов метода с параметризированными типами делаеться по схеме
<Параметризированный тип, если нужно ещё один и более>имяМетода(аргументы);
Но мы так не делаем в данном случае. Так как же этот метод получает те самые значения K, V?