以下のstart()
を呼び出すにはどうすればよいですか?
package com.example.test;
class Bar {}
public class Foo<K>
{
final private int count;
final private K key;
Foo(Builder<K> b)
{
this.count = b.count;
this.key = b.key;
}
public static class Builder<K2>
{
int count;
K2 key;
private Builder() {}
static public <K3> Builder<K3> start() { return new Builder<K3>(); }
public Builder<K2> setCount(int count) { this.count = count; return this; }
public Builder<K2> setKey(K2 key) { this.key = key; return this; }
public Foo<K2> build() { return new Foo(this); }
}
public static void main(String[] args)
{
Bar bar = new Bar();
Foo<Bar> foo1 = Foo.Builder.start().setCount(1).setKey(bar).build();
// Type mismatch: cannot convert from Foo<Object> to Foo<Bar>
Foo<Bar> foo2 = Foo.Builder<Bar>.start().setCount(1).setKey(bar).build();
// Multiple markers at this line
// - Bar cannot be resolved
// - Foo.Builder cannot be resolved
// - Syntax error on token ".", delete this token
// - The method start() is undefined for the type Foo<K>
// - Duplicate local variable fooType mismatch: cannot convert from Foo<Object> to Foo<Bar>
Foo<Bar> foo3 = Foo<Bar>.Builder.start().setCount(1).setKey(bar).build();
// Multiple markers at this line
// - Foo cannot be resolved
// - Syntax error on token ".", delete this token
// - Bar cannot be resolved
}
}
あなたは近かった:
_Foo.Builder.<Bar> start().setCount(1).setKey(bar).build();
_
乾杯! :)
追伸コンパイラがメソッドの型パラメータを独自に推測できない場合は、obj.<Type> method(...)
を呼び出して強制的にメソッドを強制できます。
あなたが使いたいかもしれないP.P.S:
_public Foo<K2> build() {
return new Foo<K2>(this);
}
_
Rawタイプの使用は避けてください。
Andreiの方法は問題ありませんが、ほとんどのプログラマーは、かなり未知の構文に苦労する可能性があります。この方法を使用する方が簡単かもしれません:
static public <K3> Builder<K3> start(Class<K3> cls) { return new Builder<K3>(); }
Foo<Bar> foo1 = Foo.Builder.start(Bar.class).setCount(1).setKey(bar).build();
クラスは、ジェネリック型を支援するためにのみ渡されます。きれいではありませんが、少なくとも構文は常識です。
もう1つのオプションは、汎用タイプのオブジェクトからすぐに開始することです。
Foo<Bar> foo1 = Foo.Builder.startWithKey(bar).setCount(1).build();
これが私がする方法です:
package odmor2018.krit.rtti.builderpattern;
import Java.lang.reflect.Field;
import Java.util.Arrays;
import Java.util.List;
import Java.util.logging.Level;
import Java.util.logging.Logger;
import Java.util.stream.Collectors;
public class Person {
private String firstName;
private String middleName;
private String lastName;
private boolean sex;
public Person(String firstName, String middleName, String lastName, boolean sex) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.sex = sex;
}
public Person() {
}
@Override
public String toString() {
return "Person{" + "firstName=" + firstName + ", middleName=" + middleName + ", lastName=" + lastName + ", sex=" + sex + '}';
}
public static class Builder {
private final Field[] fields = Person.class.getDeclaredFields();
private final List<Field> fieldsList = Arrays.asList(fields);
private final List<String> fNames = fieldsList.stream().map(f -> f.getName()).collect(Collectors.toList());
private final Person nP = new Person();
public Builder with(String fName, Object value) {
if (fNames.contains(fName)) {
int fInd = fNames.indexOf(fName);
try {
Field f = fields[fInd];
f.setAccessible(true);
f.set(nP, value);
} catch (Exception ex) {
Logger.getLogger(Person.class.getName()).log(Level.SEVERE, null, ex);
}
}
return this;
}
public Person createPerson2() {
return nP;
}
}
public static void main(String[] args) {
Person p3 = new Person.Builder()
.with("firstName", "doooobri2")
.with("sex", false)
.createPerson2();
System.err.println("p3:" + p3);
}
}