我有两个相似的类,Foo 和 Bar
public class Foo{
private String name;
public Foo(String name){
this.name = name;
}
}
public class Bar{
private String name;
public Bar(String name){
this.name = name;
}
}
我在另一个类中有两个方法创建一组 Foo(第一种方法)和 Bar(第二种方法)并且几乎相同。 第一个:
private Set<Foo> buildFoos(final List<String> names)
{
final Set<Foo> set = new HashSet<>();
for (int i = 0; i < names.size(); i++)
{
set.add(new Foo(names.get(i)));
}
return set;
}
第二个:
private Set<Bar> buildBars(final List<String> names)
{
final Set<Bar> set = new HashSet<>();
for (int i = 0; i < names.size(); i++)
{
set.add(new Bar(names.get(i)));
}
return set;
}
如您所见,这两种方法几乎相同,因此我认为我可以使用泛型来仅使用一种方法。我的方法是这样的:
private <T> Set<T> build(final Class<T> clazz, final List<String> names)
{
final Set<T> set = new HashSet<>();
for (int i = 0; i < names.size(); i++)
{
set.add(clazz.getConstructor(String.class).newInstance(names.get(i)));
}
return set;
}
我已经测试过了,它应该可以工作,但我的问题是,如果 Foo 或 Bar 有不同的构造函数会发生什么(例如,Bar 会有另一个 String 作为第二个参数)。我所能想到的就是检查类的实例并选择两个构造函数之一(像这样)
private <T> Set<T> build(final Class<T> clazz, final List<String> names)
{
final Set<T> set = new HashSet<>();
for (int i = 0; i < names.size(); i++)
{
if(clazz.isInstance(Foo.class){
set.add(clazz.getConstructor(String.class).newInstance(names.get(i)));
}
else if(clazz.isInstance(Bar.class){
set.add(clazz.getConstructor(String.class, String.class).newInstance(names.get(i), "example"));
}
}
return set;
}
有没有更好的方法来实现这一点? 这甚至是一个好习惯吗? 任何提示总是值得赞赏的。提前致谢!
最佳答案
在我看来,最好还是拿一个Function<String, T>
而不是 Class<T>
.这样您就不需要反射,调用者可以传入构造函数、工厂方法、使用多参数构造函数的 lambda,随心所欲。所以你的方法是:
private <T> Set<T> build(final Function<String, T> factory, final List<String> names) {
final Set<T> set = new HashSet<>();
for (String name : names) {
set.add(factory.apply(name));
}
return set;
}
我怀疑这可以使用流式传输更简单地编写,但这是一个单独的问题。 (虽然为了简单起见,我确实利用了这个机会使用增强型 for 循环。)
关于java - 使用不同的构造函数参数实例化泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71783429/