0

the following code

Supplier<String> newString = String::new;
System.out.println(newString.get());
// prints an empty string (nothing) to the console and then a newline character

and for the definition of Supplier get method

T get()

the get method should return T, but constructor has no return type, so why String::new can be assigned to Supplier <String>?

user1169587
  • 1,104
  • 2
  • 17
  • 34

3 Answers3

3

I think two examples will explain it, first what you wanted was a supplier for a meaningful string to print. Like,

Supplier<String> newString = () -> "test";
System.out.println(newString.get());

What you provided was an empty string. Like,

System.out.println(new String());

It's perfectly valid to produce an empty string, even if the result deviated from your expectations.

Bonus third example, to elaborate on the first example, in a lambda expression you are actually implementing a single abstract method from a functional interface - specifically Supplier<T>. Like,

Supplier<String> newString = new Supplier<String>() {
    @Override
    public String get() {
        return "test"; // originally return new String()
    }
};
System.out.println(newString.get());
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
2

Perhaps you've been reading the Java Tutorial regarding constructors, which states,

Constructor declarations look like method declarations—except that they use the name of the class and have no return type.

It's subtle, but there is a difference between that sentence and the statement in the OP.

...constructor has no return type,

Notice the Tutorial states that a constructor declaration has no return type, which is slightly different from saying that a constructor itself has no return type.

The declaration is the syntax; and we can confirm there is indeed no return type shown in the code. So there is no explicit return type. But there is an implicit return type, which is already stated as the name of the constructor. We simply don't need to repeat the return type in the declaration, because the compiler can infer it from the constructor name.

jaco0646
  • 15,303
  • 7
  • 59
  • 83
0

calling a constructor (new) creates an object and "returns" it, as you see.

Object object = new Object();

→ if a constructor would not return anything, this code was false...

But it isn't.

Therefore, the following example is okay

new Thread(new Runnable() {
  @Override public void run() {
    System.out.print("it runs.");
  }
}).start();
lue
  • 449
  • 5
  • 16
  • 1
    The constructor does not create an object, but the `new` operator. In both cases, `new Object()` and `String::new`, we are referring to an action bearing both, the creation of an object and invoking its constructor. – Holger Feb 10 '20 at 12:38