user1169587
user1169587

Reputation: 1340

Supplier interface for constructor reference

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>?

Upvotes: 0

Views: 281

Answers (3)

jaco0646
jaco0646

Reputation: 17066

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.

Upvotes: 1

user12026681
user12026681

Reputation:

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();

Upvotes: 0

Elliott Frisch
Elliott Frisch

Reputation: 201429

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());

Upvotes: 3

Related Questions