gpt4 book ai didi

Java 泛型 - 类型转换问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:03:30 24 4
gpt4 key购买 nike

我有一个通用方法,它接受要更新的类类型和该类的字段。例如:

class A {
private int a;
private int b;
}

class B {
private int c;
private int d;
}

在运行时,如果我们将类类型作为“A.class”传递,并将 fieldstoBeUpdated 作为“b”传递,访问该特定类的字段的 getter/setter 的最佳方式是什么,以便我们可以修改字段。

public <T> void find(T clazz, List<String> fieldsToBeUpdated) {
List<T> collectionList = findAll((Class<T>) clazz);
collectionList.parallelStream().forEach(p -> {
if (clazz instanceof A) {
fieldsToBeUpdated.parallelStream().forEach(classFieldName -> {
switch(classFieldName) {
case "a":((A)p).setA(10);
break;
case "b":((A)p).setB(20);
break;
}
});
}

if (clazz instanceof B) {
fieldsToBeUpdated.parallelStream().forEach(classFieldName -> {
switch(classFieldName) {
case "c":((B)p).setC(30);
break;
case "d":((B)p).setD(40);
break;
}
});
}
});
}

我已经编写了上面的代码来实现相同的目的。

但问题是我有 30 个这样的类作为参数传递给这个通用方法,其中包含要更新/修改的类的字段列表。

编写 30 个这样的 if 语句检查类类型然后将对象类型转换为该类是不正确的实现。

有没有更好的方法来达到同样的效果?

提前致谢。

最佳答案

您的AB 类似乎都提供了set/getCreatedTimeset/getUpdatedTime 方法。

如果其他 28 个左右的类也提供这些方法(正如您的问题所暗示的那样),则只需拥有一个具有这些方法的通用接口(interface),供所有类实现。

然后您可以将方法的泛型类型绑定(bind)到该接口(interface),并放弃所有 instanceof 语句和后续的显式转换。

唯一的缺点是,如果您的 List 中有一个与传递给方法的具体类无关的字段名称。

如果你想强制执行这一点,你可以在对象上使用反射来发现该字段是否按名称存在。然后,您可以使用记录的警告(或您认为合适的任何机制)轻松处理任何缺失的字段。

注意

thijs-steel 所述,如果你的“时间”方法共享相同的实现,你可以让你的 30 个类扩展一个只实现“时间”方法的公共(public)抽象父类。

或者,您可以使用 default 方法,因为您显然使用的是 Java 8。

示例

interface I {
// assuming parameters and return types here
public void setCreatedTime(ZonedDateTime z);
public void setUpdatedTime(ZonedDateTime z);
public ZonedDateTime getCreatedTime();
public ZonedDateTime getUpdatedTime();
}

// A, B etc. all implement I

public <T extends I> void find(T object, List<String> fieldsToBeUpdated) {
fieldsToBeUpdated
.parallelStream()
.forEach(
field -> {
switch(field) {
case "a": {
try {
object.getClass().getDeclaredField("a");
// we're good
object.setCreatedTime(...);
}
catch (NoSuchFieldException e) {
// TODO something
}
break;
}
// ...
}
});
}

更新

如果您的类根本不共享公共(public)字段,您可能想要完全改变整个方法。

您可能希望使用继承并在每个类中实现自己的 find 方法,而不是拥有“一个通用的方法适合所有人”的逻辑实现范例。

这将允许在每个实现中使用更小的 switch 语句,并在 default 情况下执行错误处理。

您仍然可以通过仍然采用 T extends Findablefind 方法来概括行为(其中 Findable 声明“时间”方法(现在是find 方法),并简单地在给定的T 对象上调用find

或者甚至将 FindableTimed 之间的关注点分开,并让您的类实现两者。

关于Java 泛型 - 类型转换问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44242647/

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