Как я звоню 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();
Ура! :)
P.S. Если компилятор не может самостоятельно определить параметр типа метода, вы можете принудительно вызвать его, вызвав obj.
.
P.P.S, который вы можете использовать:
public Foo<K2> build() {
return new Foo<K2>(this);
}
Избегайте использования необработанных типов.
Метод Андрея хорош, но большинство программистов, вероятно, будут бороться с довольно неизвестным синтаксисом. Возможно, было бы проще использовать этот способ:
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();
Класс передается только для помощи с универсальным типом. Это некрасиво, но, по крайней мере, синтаксис общеизвестен.
Другой вариант - начать сразу с объекта общего типа:
Foo<Bar> foo1 = Foo.Builder.startWithKey(bar).setCount(1).build();