Automatic default constructor mapping

I have a PersonFactory interface as follows:

 @FunctionalInterface public interface PersonFactory<P extends Person> { P create(String firstname, String lastname); // Return a person with no args default P create() { // Is there a way I could make this work? } } 

Person class:

 public class Person { public String firstname; public String lastname; public Person() {} public Person(String firstname, String lastname) { this.firstname = firstname; this.lastname = lastname; } } 

I want to be able to create an instance of Person as follows:

 PersonFactory<Person> personFactory = Person::new; Person p = personFactory.create(); // does not work Person p = personFactory.create("firstname", "lastname"); // works 

Is there a way to force the Java compiler to automatically select the correct constructor by matching the signature PersonFactory.create() ?

+5
source share
1 answer

One way would be to:

 default P create() { return create(null, null); } 

But I'm not sure what you wanted. The problem is that you cannot make a method reference a reference to 2 different methods (or constructors). In this case, you want Person::new refer to a constructor without parameters and a constructor with two parameters, which is impossible.

If you have:

 @FunctionalInterface public interface PersonFactory<P extends Person> { P create(String firstname, String lastname); } 

and use it like

 PersonFactory<Person> personFactory = Person::new; Person p = personFactory.create("firstname", "lastname"); 

you need to understand that the reference method Person::new refers to a constructor that takes 2 parameters. The next line simply calls it, passing parameters.

You can also write it more explicitly using the lambda expression:

 PersonFactory<Person> personFactory = (s1, s2) -> new Person(s1, s2); // see, we have the 2 Strings here Person p = personFactory.create("firstname", "lastname"); 
+5
source

Source: https://habr.com/ru/post/1238026/


All Articles