5

私は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クラス:私はこのように私のPerson Sをインスタンス化することができるようにしたい

public class Person { 
    public String firstname; 
    public String lastname; 

    public Person() {} 

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

PersonFactory<Person> personFactory = Person::new; 

Person p = personFactory.create(); // does not work 
Person p = personFactory.create("firstname", "lastname"); // works 

私はJava coを作成する方法はありますかmpilerは自動的にPersonFactory.create()の署名を照合して正しいコンストラクタを選択しますか?

+2

いいえ。唯一の賢明な方法は、 'this.create行うことである(「someDefaultFirstNameを」、「someDefaultLastName」) ; ' –

答えて

5

一つの方法は、次のことを持っているだろう:

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

しかし、私はそれはあなたが望んだか分かりません。問題は、2つの異なるメソッド(またはコンストラクタ)を参照するメソッド参照を作成できないことです。この場合、Person::newはコンストラクタを参照する必要があります。コンストラクタは2つのパラメータを取りますが、これは不可能です。あなたが持っている

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

、あなたが方法参照Person::newは、2つのパラメータを取るコンストラクタを参照していることを実現するために持っている

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

のようにそれを使用しています。次の行は、パラメータを渡すことによってそれを呼び出します。

あなたはまた、より明示的にラムダ式を使用して、それを書くことができます:あなたは、デフォルトのメソッドを実装することができ

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