Как использовать [TypeArguments] со ссылкой на конструктор в Java 8?

Раздел 15.13 Спецификации языка Java для Java 8 описывает эту форму синтаксиса ссылки на метод для создания ссылки на конструктор:

    ClassType :: [TypeArguments] new

Например:

    String s = "abc";
    UnaryOperator<String> test0 = String::new; // String(String) constructor.
    String s0 = test0.apply(s);
    System.out.println("s0 = " + s0); // Prints "abc".

    char[] chars = {'x','y','z'};
    Function<char[], String> test1 = String::new; // String(char[]) constructor.
    String s1 = test1.apply(chars);
    System.out.println("s1 = " + s1); // Prints "xyz"

Это все работает нормально, но кажется, что абсолютно все (кроме примитивов) также может быть предоставлено для [TypeArguments], и все по-прежнему работает:

Вот глупый пример, чтобы доказать это:

    Function<String, String> test2 = String::<LocalDateTime, Thread[]>new; // Compiles !!!???
    String s2 = test2.apply("123");
    System.out.println("s2 = " + s2); // Prints "123"

Возникает несколько вопросов:

[1] Поскольку класс String даже не использует обобщенные значения, действительно ли компилятор допускает создание этой ссылки на конструктор test2 с этими бессмысленными [TypeArguments]?

[2] Что может быть полезным примером использования [TypeArguments] при создании ссылки на конструктор?

[3] При каких условиях необходимо указывать [TypeArguments] при создании ссылки на конструктор?

1 ответ

1 15.13.1. Объявление во время компиляции ссылки на метод

Если выражение ссылки на метод имеет форму ClassType:: [TypeArguments] new, потенциально применимые методы представляют собой набор условных методов, соответствующих конструкторам ClassType....

В противном случае потенциальные методы-члены-члены являются конструкторами ClassType и обрабатываются так, как если бы они были методами с возвращаемым типом ClassType. Среди этих кандидатов выбираются методы с соответствующей доступностью, arity (n) и аргументом типа arity (производным от [TypeArguments]), как указано в §15.12.2.1.

JLS 15.12.2.1. Определить потенциально применимые методы

Этот пункт подразумевает, что неуниверсальный метод может быть потенциально применим к вызову, который предоставляет явные аргументы типа. Действительно, это может оказаться применимым. В таком случае аргументы типа будут просто игнорироваться.

2 Всякий раз, когда конструктор параметризован. Я никогда не сталкивался с одним.

public class Foo {

   public <T> Foo(T parameter) {
...
Function<String, Foo> test = Foo::<String>new

3 Когда компилятор не может определить тип.

Другие вопросы по тегам