1

Section 15.13 of the Java Language Specification for Java 8 describes this form of the method reference syntax for creating a constructor reference:

    ClassType :: [TypeArguments] new

For example:

    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"

That all works fine, but it seems that absolutely anything (excluding primitives) can be also supplied for the [TypeArguments] and everything still works:

Here's a silly example to prove the point:

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

A few questions arising:

[1] Since the String class doesn't even use generics, is it valid that the compiler allows the creation of that test2 constructor reference with those meaningless [TypeArguments]?

[2] What would be a meaningful example of using [TypeArguments] when creating a constructor reference?

[3] Under what conditions is it essential to specify [TypeArguments] when creating a constructor reference?

4

1 回答 1

5

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当编译器无法推断类型时。

于 2015-03-20T18:45:27.860 回答