Подтвердить что ты не робот

Элемент Cast в Java Для каждого утверждения

Возможно ли (или даже целесообразно) использовать элемент, полученный из a для каждого утверждения в самом заявлении? Я знаю, что каждый элемент в списке будет иметь тип <SubType>.

то есть:.

List<BaseType> list = DAO.getList();  
for(<SubType> element : list){ 
    // Cannot convert from element type <BaseType> to <SubType>
    ...
}

а не:

List <BaseType> list = DAO.getList();
for(<BaseType> el : list){
    <SubType> element = (<SubType>)el;
    ...
}
4b9b3361

Ответ 1

Вы действительно знаете, что каждая запись будет подтипом? DAO просто должен выполнить контракт List<BaseType>, и если вы принимаете подкласс, то я думаю, что-то где-то не так. Я, возможно, сконцентрируюсь на правильном использовании интерфейса для DAO, и пусть он по контракту вернет то, что вы хотите.

Ответ 2

По всем причинам, указанным другими, вы не должны этого делать. Однако, если вы не можете изменить интерфейс, возможно следующее:

for (BaseType element : list) {
    SubType subType = (SubType)element;
    ...
}

Насколько я знаю, это единственный способ сделать это и оставаться по-настоящему безопасным по типу, т.е. не полагаться на стирание типа, чтобы поймать любые проблемы, которые он не будет делать до тех пор, пока значительно позже.

Я понимаю, что это НЕ ТОЧНО, что вы искали, но оно справляется с кастингом.

Ответ 3

Фактически возможно комбинировать трансляцию с циклом for, например:

List<BaseType> list = DAO.getList();  
for (SubType subType : ((List<SubType>) list)){ 
    ...
}

Или вы можете использовать этот слегка более чистый шаблон:

List<SubType> list = (List<SubType>) DAO.getList();  
for (SubType subType : list){ 
    ...
}

Вы получите предупреждение о немедленном предупреждении от компилятора Java, если только вы его не подавите. Эффект первой формы будет фактически идентичен тому, чтобы различать каждый элемент внутри цикла. Вторая форма также предусматривает, что новые дополнения к списку должны соответствовать SubType.

Обратите внимание, что это НЕ будет работать с массивами, поскольку массивы имеют разные типы времени выполнения. Другими словами, BaseType [] не поддается SubType []. Вы можете использовать API массивов, чтобы обойти это, например:

BaseType[] array = DAO.getArray();
for (SubType subType : Arrays.<SubType>asList(array)) {
    ...
}

Ответ 4

Возможно, да! но не дай бог, почему? Мои ранние попытки в моей карьере сделали это, и я узнал. Преимущество программирования на интерфейсах всегда имеет преимущество. Я всегда получаю вопросы от младших разработчиков по поводу обработки случаев, когда только подтипы имеют необходимые методы/функциональные возможности.

Скажите класс Animal с подтипом Dog, имеющим метод bark(). Им нужна функция bark(). Реальная проблема заключается в том, что они хотят, чтобы поведение общения с животными не было лаем(), но животное говорило(). Таким образом, новый класс подкатегории Cat не потребует мяу(). А как насчет этого: - Моя собака образует пачку, но кошки этого не делают. Поведение в виде ответа() не принадлежит одной собаке. Pack - это другой аспект, передать пакет всем объектам и попросить объекты присоединиться к пакету. (Шаблон посетителя/шаблон адаптера). Класс My Wolf может использовать одно и то же поведение.

Я жестко отношусь к этому, нет, если это всего лишь 1 случай, я в порядке. Если ответ я не уверен, тогда вам лучше играть безопасно, работая по контрактам интерфейса.

Ответ 5

Если вы не являетесь частью коллекций Google, вы можете обернуть список с помощью метода transform. В вашем случае он будет очень эффективным и полностью совместимым. Я бы сказал, что это метод обертки, как предположил Брайан.

public List< SubType > fromDao ( )
{
    // Put a comment for maintainer

    // Lists from DAO always contain SubTypes
    return
        Lists.transform(
            DAO.getList( ),
            new Function< BaseType, SubType >( )
            {
                public SubType apply ( final BaseType from )
                {
                    return (SybType) from;
                }
            };
}