【发布时间】:2010-09-27 17:07:43
【问题描述】:
我有一个方法fetchObjects(String),它预计会返回一个Contract 业务对象的数组。 className 参数告诉我应该返回什么样的业务对象(当然这在这种解释的情况下没有意义,因为我已经说过我会返回Contracts,但这基本上是我真实的情况设想)。所以我从某处获取条目集并加载集合条目的类(其类型由className 指定)。
现在我需要构造返回的数组,所以我使用Set的toArray(T[])方法。使用反射,我为自己构建了一个空的 Contracts 数组。 但是, 这给了我一个静态类型的值Object!所以接下来我需要将其转换为适当的类型,在本例中为Contract[](请参阅下面清单中的“星号下划线”部分)。
我的问题是:有没有办法以及如何像我在清单中那样转换为Contract[],但只能通过className确定数组元素的类型(Contract) /em>(或entriesType)?换句话说,我想要做的基本上是这样的:(entriesType[]) valueWithStaticTypeObject,其中 entriesType 被通过classname 参数指定的类替换,即Contract。
这在某种程度上是不可能的,还是可以通过某种方式完成?也许使用泛型?
package xx.testcode;
import java.util.HashSet;
import java.util.Set;
class TypedArrayReflection {
public static void main(String[] args) {
try {
Contract[] contracts = fetchObjects("Contract");
System.out.println(contracts.length);
} catch (ClassNotFoundException e) {}
}
static Contract[] fetchObjects(String className) throws ClassNotFoundException {
Class<?> entriesType = Class.forName("xx.testcode."+className);
Set<?> entries = ObjectManager.getEntrySet(className);
return entries.toArray(
(Contract[]) java.lang.reflect.Array.newInstance(
/********/ entriesType, entries.size()) );
}
}
class Contract { } // business object
class ObjectManager {
static Set<?> getEntrySet(String className) {
if (className.equals("Contract"))
return new HashSet<Contract>();
return null; // Error
}
}
谢谢。
更新: 使用取自CodeIdol 的类型安全方法
toArray,我更新了我的fetchObjects 方法:
static Contract[] fetchObjects(String className) throws ClassNotFoundException {
Class<?> entriesType = Class.forName("xx.testcode."+className);
Set<?> entries = ObjectManager.getEntrySet(className);
return toArray(entries, entriesType); // compile error
// -> "method not applicable for (Set<capture#3-of ?>, Class<capture#4-of ?>)"
}
public static <T> T[] toArray(Collection<T> c, Class<T> k) {
T[] a = (T[]) java.lang.reflect.Array.newInstance(k, c.size());
int i = 0;
for (T x : c)
a[i++] = x;
return a;
}
我需要做些什么来摆脱评论中引用的编译器错误?我是否必须在 getEntrySet 方法的返回类型中指定 Set<Contract> 才能正常工作?感谢您的任何指点。
【问题讨论】:
-
entryType类不是Contract的子类怎么处理?
-
entriesType 不一定是 Contract 的子类型。它可以是宠物、朋友、爱好——任何你可能收藏的东西。在我的示例中,客户将拥有一系列合同。
标签: java generics reflection casting reification