How do I use [TypeArguments] with a constructor reference in Java 8?

302 Views Asked by At

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?

1

There are 1 best solutions below

4
On

1 15.13.1. Compile-Time Declaration of a Method Reference

If the method reference expression has the form ClassType :: [TypeArguments] new, the potentially applicable methods are a set of notional methods corresponding to the constructors of ClassType. ...

Otherwise, the candidate notional member methods are the constructors of ClassType, treated as if they were methods with return type ClassType. Among these candidates, the methods with appropriate accessibility, arity (n), and type argument arity (derived from [TypeArguments]) are selected, as specified in §15.12.2.1.

JLS 15.12.2.1. Identify Potentially Applicable Methods

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.

2 Whenever a constructor is parameterized. I've never stumbled upon one.

public class Foo {

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

3 When the compiler can't infer the type.