Что, если опускать аргументы (типы) для методов-дженериков?

125
03 февраля 2021, 07:30

Я знаю, что если не указывать аргументы (вообще без угловых скобок) для классов-дженериков, то аргументами будет считаться тип Objcect, и что так "никто не делает".

1. Но за что принимаются опущенные аргументы в случаи с методами-дженерииками? Видимо по коду - не за Object):

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Solution {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<Integer>();
        list1.add(0);
        Collections.fill(list1, 111);
        System.out.println(list1); // [111] - сработало
    }
}
  • Метод fill: static <T> void fill(List<? super T> list, T obj)

  • Для него аргумент мы не указали, но если бы за аргумент принялся
    Object, то метод бы не сработал в связи с: (List<? super T> list, T obj)

2. Стоит ли так делать (полностью опускать угловые скобки для методов-дженериков? IDE мне никогда не предлагает их ставить...

Answer 1

1. Но за что принимаются опущенные аргументы в случаи с методами-дженерииками?

Реальные типы выводятся компилятором. Вывод типов — сложный и запутанный процесс с кучей нюансов. Ему посвящена целая глава спецификации Java (Chapter 18. Type Inference).

Если коротко, то компилятор пытается на основе переданных аргументов подобрать наиболее специфичный подходящий тип.

Для этого он берет метод:

<T> void fill(List<? super T> list, T obj)

, фактические аргументы и возвращаемое значение (здесь нет):

 Collections.fill(List<Integer>, int);

строит систему ограничений на T, принимает в расчет возможность оборачивания значений и определяет, что в данном случае Integer подходит как значение для T.

Если вывести тип не получится, то компилятор выдаст ошибку. Например, код:

Collections.fill((list1, "111");

Приведет к ошибке:

error: method fill in class Collections cannot be applied to given types;
        Collections.fill(list1, "111");
                   ^
  required: List<? super T>,T
  found: List<Integer>,String
  reason: inferred type does not conform to upper bound(s)
    inferred: String
    upper bound(s): Integer,Object
  where T is a type-variable:
    T extends Object declared in method <T>fill(List<? super T>,T)

Т.е. компилятор не нашел такого T, которое приняло бы как Integer так и String.

2. Стоит ли так делать (полностью опускать фигурные скобки для методов-дженериков?

Да, не нужно явно указывать тип без необходимости. Если Вы не используете несформированные типы, то в большинстве случаев компилятор сам справится с выводом.

Явное указание может понадобится в тех случаях, когда компилятор по каким-то причинам не может вывести нужный тип. Например, если у метода нет аргумента и по возвращаемому значению нельзя определить тип:

//метод принимает Object, но нужно передать ему список строк
someMethod(Collections.<String>emptyList());
Answer 2

"Для него аргумент мы не указали"

указали неявно, подав аргумент типа int, запакованный затем в Integer.

"Стоит ли так делать (полностью опускать фигурные скобки?)"

Вы, видимо, хотели сказать "угловые"? Ну если это не затрудняет чтение текста, то почему бы и нет.

READ ALSO
TreeSet метод first() java

TreeSet метод first() java

Подскажите как можно реализовать метод который должен возвращать самый малый элемент

98
Как по странице в браузере найти определенную форму в коде?

Как по странице в браузере найти определенную форму в коде?

Есть очень большой веб проект, как мне найти, например, эту форму в коде? Пользуюсь intellij ideaНа форму нужно добавить одно поле, но искать ее вручную...

94
Обработка одновременного нажатия нескольких кнопок в javafx

Обработка одновременного нажатия нескольких кнопок в javafx

У меня есть панель, на которой рисуются графики функцийС помощью этого метода на неё повешен слушатель

129
Java Json десериализация только нужных данных

Java Json десериализация только нужных данных

Java Json десериализация только нужных данных Как содержимое которое находится в «Campaigns» положить как объект в массив? Желательно при помощи...

116