如何在Java 8中将[TypeArguments]与构造函数引用一起使用?

sko*_*isa 2 java-8 method-reference constructor-reference

Java语言规范Java 8的第15.13节描述了这种形式的方法参考语法,用于创建构造函数引用:

    ClassType :: [TypeArguments] new
Run Code Online (Sandbox Code Playgroud)

例如:

    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"
Run Code Online (Sandbox Code Playgroud)

一切正常,但似乎绝对任何东西(不包括原语)也可以为[TypeArguments]提供,一切仍然有效:

这是一个愚蠢的例子来证明这一点:

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

提出几个问题:

[1]由于String类甚至不使用泛型,编译器是否允许使用那些无意义的[TypeArguments]创建test2构造函数引用是否有效?

[2] 在创建构造函数引用时使用[TypeArguments]会有什么有意义的例子?

[3]在什么条件下创建构造函数引用时必须指定[TypeArguments]

a b*_*ver 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
Run Code Online (Sandbox Code Playgroud)

3当编译器无法推断出类型时.

  • `ClassType :: [TypeArguments] new`**是**方法参考.没有构造函数引用(就规范而言).JLS将其描述为对应于构造函数_的_**名义方法**的引用.争论反对JLS是没有意义的. (2认同)