Автоматическое сопоставление конструктора в методе по умолчанию
У меня есть PersonFactory
Интерфейс следующим образом:
@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
учебный класс:
public class Person {
public String firstname;
public String lastname;
public Person() {}
public Person(String firstname, String lastname) {
this.firstname = firstname;
this.lastname = lastname;
}
}
Я хочу быть в состоянии создать свой экземпляр Person
вот так:
PersonFactory<Person> personFactory = Person::new;
Person p = personFactory.create(); // does not work
Person p = personFactory.create("firstname", "lastname"); // works
Есть ли способ, которым я мог бы заставить компилятор Java автоматически выбирать правильный конструктор, сопоставляя подпись PersonFactory.create()
?
1 ответ
Одним из способов было бы иметь следующее:
default P create() {
return create(null, null);
}
Но я не уверен, что ты этого хотел. Проблема в том, что вы не можете сделать ссылку на метод ссылающимся на 2 разных метода (или конструктора). В этом случае вы хотите Person::new
ссылаться на конструктор без параметров и конструктор с 2 параметрами, что невозможно.
Когда у тебя есть:
@FunctionalInterface
public interface PersonFactory<P extends Person> {
P create(String firstname, String lastname);
}
и использовать его как
PersonFactory<Person> personFactory = Person::new;
Person p = personFactory.create("firstname", "lastname");
Вы должны понимать, что метод-ссылка Person::new
ссылается на конструктор, принимающий 2 параметра. Следующая строка просто вызывает ее, передавая параметры.
Вы также можете написать это более подробно, используя лямбда-выражение:
PersonFactory<Person> personFactory = (s1, s2) -> new Person(s1, s2); // see, we have the 2 Strings here
Person p = personFactory.create("firstname", "lastname");