我想做的事情如下:
假设getClassFromString()
和getAllObjectsFromRepositoryByClass()
已经存在。
为什么我不能使用Class<T extends Named & HasId>
.
我尝试泛化类本身,但不能使用像 T.class
这样的东西等等
public interface Named { String getDisplayName(); }
public interface HasId { String getId(); }
public class Foo {
public List<PairItem> getPairItems(String typeId) {
Class<T extends Named & HasId> clazz = getClassFromString(typeId);
List<T> allObjects = getAllObjectsFromRepositoryByClass(clazz);
List<PairItem> items = new ArrayList<>();
for (clazz obj : allObjects) {
items.add(obj.getDisplayName(),ibj.getId());
}
return items;
}
最佳答案
您可以通过以下方式更改 Foo
类:
public class Foo {
public <T extends Named & HasId> List<PairItem> getPairItems(String typeId) {
Class<?> classFromString = getClassFromString(typeId);
// Java 8 seems to be unable to chain asSubclass-calls. These are merely to verify our unchecked cast
classFromString.asSubclass(Named.class);
classFromString.asSubclass(HasId.class);
//noinspection unchecked
return getPairItems((Class<T>) classFromString);
}
public <T extends Named & HasId> List<PairItem> getPairItems(final Class<T> clazz) {
List<T> allObjects = getAllObjectsFromRepositoryByClass(clazz);
List<PairItem> items = new ArrayList<>();
for (T obj : allObjects) {
items.add(new PairItem(obj.getDisplayName(), obj.getId()));
}
return items;
}
}
这解决了多个边界的问题,因为它们只允许用于 documentation 的类型参数。 .;我也猜想
If one of the bounds is a class, it must be specified first.
导致 asSubclass()
调用无法链接的问题,否则我们可以删除未经检查的强制转换。
第二种方法可以从流 API 中获益,如下所示:
public <T extends Named & HasId> List<PairItem> getPairItems(final Class<T> clazz) {
List<T> allObjects = getAllObjectsFromRepositoryByClass(clazz);
return allObjects.stream()
.map(obj -> new PairItem(obj.getDisplayName(), obj.getId()))
.collect(Collectors.toList());
}
总的来说,我假设您想要实例化 PairItem
并拆分该方法,以便有一个未检查的部分和一个完全检查的部分。
关于Java 多重边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27730274/