Java 8 и обобщенный вывод типа цели

Я установил последний JDK 8 ea b114 для тестирования новых языковых функций. Однако вывод в цепочке вызовов, похоже, еще не работает.

Если я пишу:

Iterator<String> it = new ArrayList<>().iterator();

компилятор даст мне ошибку.

Однако вывод в позиции аргументов хорошо работает.

Может быть, вывод в цепочку вызовов не будет вставлен?

Ответ 1

Последняя спецификация (Public Review) доступна по адресу jcp.org. В части D содержится абзац, в котором обсуждается этот вопрос.

Приемник в вызове метода, в полевом доступе и т.д. (exp.foo()) не является политическим выражением, потому что целевой тип неизвестен - невозможно было бы перечислить каждый тип, который имеет определенный член (foo, в этом случае). Был некоторый интерес к разрешению вывода к "цепочке": в a(). B(), передавая информацию о типе от вызова b к вызову a. Это добавляет еще одно измерение сложности алгоритма вывода, поскольку частичная информация должна проходить в обоих направлениях; он работает только тогда, когда стирание возвращаемого типа a() фиксировано для всех экземпляров (например, List). Эта функция не очень хорошо вписывается в модель выражения poly, поскольку целевой тип не может быть легко получен.

Ответ 2

Как сказал @Holger, Java8 улучшил контекстуальный вывод, так что это работает

public static <T> Iterator<T> iter(Iterable<T> i)
{
    return i.iterator();
}

public static void main(String[] args)
{
    Iterator<String> it = iter( new ArrayList<>() );
                \____________________________/
}

Это не работает в Java7 - вывод в new ArrayList<>() не может зависеть от контекста.


Это будет огромное изменение в языке, чтобы делать то, что вы хотите в вопросе. Джон Роуз начал аналогичное обсуждение, см. http://mail.openjdk.java.net/pipermail/lambda-dev/2013-July/010531.html


Слишком большой вывод и слишком много контекстной зависимости могут быть плохими. Это не так много, что компилятор не может справиться со сложностью - он может. Это о том, смогут ли люди программисты справиться с этим. Я чувствую, что Java8 уже находится на опасном уровне, что для людей будет сложно разбираться в коде.