在循环中实例化对象是每个开发人员都会采用的常用方法。
我们在循环内实例化具有不同泛型和集合类型的不同对象,这是不可建议的。定义获取实例的私有方法可以解决问题。但我正在寻找达到同样目标的通用方法。
示例:在以下代码中
if (CollectionUtils.isNotEmpty(xList)) {
for (final X x : xList) {
final List<Y> yList = new ArrayList<Y>();
final Z z = new Z();
populateYList(yList);
if (CollectionUtils.isNotEmpty(yList)) {
// do something
}
}
当我们采用通用方式时,对象安全吗?我的努力很少在
之下private <T> List<T> getCollectionIntializer(Class<T> type) {
return new ArrayList<T>();
}
private <T> T getIntializer(Class<T> clazz) {
T c = null;
try {
c = (T) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return c;
}
最后我的代码看起来像
if (CollectionUtils.isNotEmpty(xList)) {
for (final X x : xList) {
final List<Y> yList = getCollectionIntializer(Y.class);
final Z z = getIntializer(Z.class);
populateYList(yList);
if (CollectionUtils.isNotEmpty(yList)) {
// do something
}
}
这是一种在单独的静态类中隔离这些方法的安全方法,以便可以在所有类中使用它。实例化超出类范围的对象?
提前分享想法和感谢
答案 0 :(得分:1)
这完全取决于你使用这些方法获得的集合或对象做了什么。如果有人可能用类型来调用它而你没有预料到这会导致错误,我认为最好限制对这些方法或类的访问。
如果您希望这些方法中只有具有特定超类的子类,则可以使用通配符。例如:
private <T extends Number> List<T> getCollectionIntializer(Class<T> type) {
return new ArrayList<T>();
}
如果我以这种方式调用getCollectionIntializer方法:
SomeClass someClass = new SomeClass();
List<SomeClass> list = someClass.getCollectionIntializer(someClass.getClass());
我将收到编译错误:
Error:(27, 41) java: method getCollectionIntializer in class SomeClass cannot be applied to given types;
required: java.lang.Class<T>
found: java.lang.Class<capture#1 of ? extends SomeClass>
reason: inferred type does not conform to upper bound(s)
inferred: capture#1 of ? extends SomeClass
upper bound(s): java.lang.Number
可能会有所帮助。
答案 1 :(得分:1)
如果可能的话,应该避免反思。这里似乎没有任何东西需要它。
通常对于集合,类型参数就足够了,所以我们不必做太多困难。
final List<Y> yList = new ArrayList<>();
要创建对象,通常应用抽象工厂模式。 java.util.function.Supplier
提供了一个通用界面。可以使用对构造函数语法的方法引用来获取Supplier
。
myCode(MyZ::new);
[...]
public static <Z> List<Z> myCode(Supplier<Z> supplier) {
List<Z> zList = new ArrayList<>();
zList.add(suppler.get());
return zList;
}