Приведение к классу, который определяется во время выполнения
У меня есть методfetchObjects(String)
ожидается, что вернет массивContract
бизнес-объекты.className
Параметр говорит мне, какие бизнес-объекты мне следует возвращать (конечно, в данном случае это не имеет смысла, потому что я уже сказал, что вернусьContract
с, но это в основном ситуация, которую я имею в моем реальном сценарии). Таким образом, я получаю набор записей откуда-то и загружаю класс записей коллекции (тип которых определяетсяclassName
).
Теперь мне нужно построить массив для возврата, поэтому я используюSet
«stoArray(T[])
метод. Используя рефлексию, я создаю пустой массив Contracts.Но, это дает мне значение статического типаObject
! Итак, затем мне нужно привести его к соответствующему типу, который в данном случаеContract[]
(см. часть с подчеркиванием звездочкой в листинге ниже).
Мой вопрос: есть ли способ и какContract[]
как я делаю в списке,но определение типа элементов массива (Contract
) только черезclassName
(или жеentriesType
)? Другими словами, я хотел бы сделать следующее:(entriesType[]) valueWithStaticTypeObject
, где recordsType должен быть заменен классом, указанным через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
}
}
Благодарю.
Обновить: Используя типобезопасный методtoArray
, взято изCodeIdolЯ обновил свой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;
}
Что мне нужно сделать, чтобы избавиться от ошибки компилятора, указанной в комментарии? Обязательно ли указыватьSet<Contract>
в типе возврата моегоgetEntrySet
метод, чтобы это могло работать? Спасибо за любые указатели.