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

Java 8 在Java8中,如何将[TypeArguments]与构造函数引用一起使用?,java-8,method-reference,constructor-reference,Java 8,Method Reference,Constructor Reference,Java 8的Java语言规范第15.13节描述了用于创建构造函数引用的这种形式的方法引用语法: ClassType :: [TypeArguments] new 例如: String s = "abc"; UnaryOperator<String> test0 = String::new; // String(String) constructor. String s0 = test0.apply(s); System.out.printl

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

    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"
String s=“abc”;
UnaryOperator test0=String::new;//字符串(String)构造函数。
字符串s0=test0.apply;
System.out.println(“s0=“+s0”);//打印“abc”。
char[]chars={'x','y','z'};
函数test1=String::new;//字符串(char[])构造函数。
字符串s1=test1.apply(字符);
System.out.println(“s1=“+s1”);//打印“xyz”
这一切都很好,但似乎绝对可以为[TypeArguments]提供任何东西(不包括原语),并且所有东西都仍然有效:

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

    Function<String, String> test2 = String::<LocalDateTime, Thread[]>new; // Compiles !!!???
    String s2 = test2.apply("123");
    System.out.println("s2 = " + s2); // Prints "123"
Function test2=String::new;//编译!!!???
字符串s2=test2.apply(“123”);
System.out.println(“s2=“+s2”);//打印“123”
出现了几个问题:

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

[2] 创建构造函数引用时使用[TypeArguments]的一个有意义的例子是什么

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

1

如果方法引用表达式的形式为ClassType::[TypeArguments]new,则可能适用的方法是一组与ClassType的构造函数相对应的概念方法。

否则,候选概念成员方法是类类型的构造函数,被视为具有返回类型ClassType的方法。根据§15.12.2.1的规定,在这些候选方法中,选择具有适当可访问性、算术性(n)和类型参数算术性(源自[TypeArguments])的方法

此子句意味着非泛型方法可能适用于提供显式类型参数的调用。事实上,它可能被证明是适用的。在这种情况下,类型参数将被忽略

2每当构造函数被参数化时。我从来没有偶然发现过

public class Foo {

   public <T> Foo(T parameter) {
...
Function<String, Foo> test = Foo::<String>new
公共类Foo{
公共Foo(T参数){
...
函数测试=Foo::新建
3当编译器无法推断类型时。

1

如果方法引用表达式的形式为ClassType::[TypeArguments]new,则可能适用的方法是一组与ClassType的构造函数相对应的概念方法。

否则,候选概念成员方法是类类型的构造函数,将其视为具有返回类型类类型的方法。在这些候选方法中,选择具有适当可访问性、arity(n)和类型参数arity(源自[TypeArguments])的方法,如§15.12.2.1所述

此子句意味着非泛型方法可能适用于提供显式类型参数的调用。实际上,它可能是适用的。在这种情况下,类型参数将被忽略

2每当构造函数被参数化时。我从未偶然发现过

public class Foo {

   public <T> Foo(T parameter) {
...
Function<String, Foo> test = Foo::<String>new
公共类Foo{
公共Foo(T参数){
...
函数测试=Foo::新建

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

Re[1],JLS第15.12节涉及方法调用,而不是类实例创建,这将在15.9中讨论。第15.9.1节说明如果ClassOrInterfaceTypeToInstallate以TypeArguments结尾,则ClassOrInterfaceTypeToInstallate必须表示格式良好的参数化类,否则会发生编译时错误。"。这表明我给出的最后一个示例不应该编译,因为String类不使用类型参数。而且我很谨慎地假设方法引用的任何规则都会自动应用于构造函数引用。15.13指的是15.12.2.1。这是关于找到合适的方法。在c中,构造函数被视为方法ase.它毕竟称为方法引用。15.9.在这里不适用,因为您的示例是关于方法引用的。我扩展了我的答案。Re“您的示例是关于方法引用的”:嗯……是和否。我对方法引用使用了双冒号语法,但我所有的示例显然都是关于构造函数引用的(与方法引用相反),因为它们都使用“::new”。如果JLS声明如果[TypeArgument]对于构造函数引用来说,它没有意义或不相关。但我看不到这一点,因此它看起来像是编译器错误;我的最后一个示例显然包含编译器乐于接受的胡言乱语。
ClassType::[TypeArguments]new
是一个方法引用。没有构造函数引用这样的东西(至于规范)。JLS将其描述为对与构造函数相对应的概念方法的引用。没有必要反对JLS.Re[1],JLS第15.12节涉及方法调用,而不是类实例创建,这将在15.9中讨论。第15.9.1节说明如果ClassOrInterfaceTypeToInstallate以TypeArguments结尾,则ClassOrInterfaceTypeToInstallate必须表示格式良好的参数化类,否则会发生编译时错误。"。这表明我给出的最后一个示例不应该编译,因为String类不使用类型参数。而且我很谨慎地假设方法引用的任何规则都会自动应用于构造函数引用。15.13指的是15.12.2.1。这是关于找到合适的方法。在c中,构造函数被视为方法毕竟,它被称为方法引用。15.9.在这里不适用,因为您的示例是关于met的