gpt4 book ai didi

java - 如何在泛型类中正确键入 no-arg 和 withVar 构造函数?

转载 作者:行者123 更新时间:2023-12-02 01:22:16 25 4
gpt4 key购买 nike

我正在开发一个(Java 8+)类,我想使用一种“构建器”模式来构建该类,在该模式中,您将无参构造函数链接到一个或多个返回相同对象的 setter 。基本上这是我的类(class):

public class MyClass {
private int foo;
private String bar;

public MyClass() {
System.out.println("initializing instance of MyClass");
}
public MyClass withFoo(int foo) {
this.foo=foo;
return this;
}
public MyClass withBar(String bar) {
this.bar = bar;
return this;
}
}

初始化它的典型方式是

MyClass anInstance = new Myclass().withFoo(42).withBar("helloworld");

这是一个很好的模式,但我以前从未将它与泛型类一起使用过。现在我想泛化我的类(class)。我对类签名和构造函数、withFoo 和 withBar 方法进行了更改:

public class MyClass<T> {
private int foo;
private String bar;

public MyClass() {
System.out.println("initializing instance of MyClass");
}
public MyClass<T> withFoo(int foo) {
this.foo=foo;
return this;
}
public MyClass<T> withBar(String bar) {
this.bar = bar;
return this;
}
}

请注意foobar他们自己不会改变类型。没有类型 <T>将通过 withVar() 传入方法。

我有一些线索表明这不是最好的方法。标准的无参数构造函数似乎工作正常:

  • 工作正常: MyClass<Float> myInstance = new MyClass<>();

但是如果我添加 withVar函数我在编译时收到错误(java: 不兼容类型: MyClass 无法转换为 MyClass)。

  • 无法编译: MyClass<Float> myInstance = new MyClass<>().withFoo(42);

我可以通过指定类型两次来使其工作,如下所示:

  • 工作正常: MyClass<Float> myInstance = new MyClass<Float>().withFoo(42);

有没有更好的方法来编码,以便泛型类型正确地转移到赋值运算符的右侧?

最佳答案

我能做到这一点的唯一两种方法是添加一个指定类型的构造函数参数:

MyClass<Float> instance = new MyClass<>(0.f).withFoo(42).withBar("helloworld");

或者通过添加“终端转换”方法:

public class MyClass<T> {
// ...

public MyClass() { ... }

public <U> MyClass<U> cast() {
MyClass<U> copy = new MyClass<>();
return copy.withFoo(foo).withBar(bar);
}

public MyClass<T> withFoo(int foo) { ... }
public MyClass<T> withBar(String bar) { ... }
}

然后您可以像这样调用:

MyClass<Float> instance = new MyClass<>().withFoo(42).withBar("helloworld").cast();
<小时/>

第三种方法是提供一个工厂方法来创建 MyClass<Float>具体实例:

static MyClass<Float> newFloatInstance() { return new MyClass<>(); }

然后您可以像这样调用:

MyClass<Float> instance = newFloatInstance().withFoo(42).withBar("helloworld");

但我想您可能并不真的希望每种可能的类型都具有工厂方法。

<小时/>

但请注意,如果您能够在不向绑定(bind) MyClass 实例的强制转换方法(或构造函数)提供某些内容的情况下执行此操作,对于其类型参数,您实际上并不需要类上的类型变量。

您可以将类型变量推送到需要该类型变量的方法上:

public class MyClass {
// ...

public <T> T doSomethingToSpecificType(List<T> list, T arg) {
// do something type-specific.
}
}

关于java - 如何在泛型类中正确键入 no-arg 和 withVar 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57479725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com