Во-первых, ваш код не является безопасным. Он может вызывать исключение класса при выполнении во время выполнения. Вы должны иметь
private void saveConcreteDOs(AbstractDO[] theEntities) {
entityMap.put(theEntities.getClass().getComponentType(), theEntities);
}
Вы можете иметь только однородные массивы во время выполнения, а элемент [0] имеет тот же тип, что и тип компонента массива. Тем не менее, нет никакого способа узнать, что, изучая этот класс в одиночку.
С помощью этого исправленного кода супер-умный компилятор может доказать, что getConcreteDOs()
является безопасным по типу. Однако джавак не такой умный. Для спецификации языка требуется бросить предупреждение.
Как правило, нет способа выразить более сложные отношения между ключами и значениями на Java. Инвариант, что значение представляет собой массив, тип компонента которого является ключом, поддерживается только в вашей голове.
Теперь посмотрим на эту версию без массива:
private Map<Class<? extends AbstractDO>, AbstractDO> map;
protected <E extends AbstractDO> E getConcreteDOs(Class<E> theType)
{
AbstractDO obj = map.get(theType);
return theType.cast(obj);
}
Это не имеет никакого предупреждения, но это своего рода обман. Class.cast()
скрывает предупреждение для нас, вот и все.
Это не помогает версии массива, нет T[] castArray(Object[])
в Class<T>
.Вы можете сделать один метод самостоятельно, эффективно скрыть предупреждение в нем.
Или вы можете это сделать, но это действительно излишне липкое. Не бойтесь безответного предупреждения о броске, если вы знаете, что делаете, и тщательно изучили свою программу для обеспечения безопасности типа.
protected <E extends AbstractDO> E[] getConcreteDOs(Class<E[]> arrayType)
{
AbstractDO[] array = map.get(arrayType.getComponentType());
return arrayType.cast(array);
}
...
X[] array = getConcreteDOs(X[].class);
только в том случае, пожалуйста, игнорировать NPE и подобные ошибки - код сокращенный вариант, конечно – topchef
Массивы и дженерики не смешиваются хорошо, лучше использовать List вместо этого. – starblue
спасибо, это вариант. – topchef