Приведение элемента в Java для каждого оператора - PullRequest
18 голосов
/ 19 марта 2010

Возможно ли (или даже желательно) привести элемент, извлеченный из, для каждого оператора в самом операторе? Я знаю, что каждый элемент в списке будет иметь тип <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;
    ...
}

Ответы [ 5 ]

17 голосов
/ 19 марта 2010

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

15 голосов
/ 19 марта 2010

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

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

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

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

11 голосов
/ 21 марта 2012

Фактически возможно объединить приведение с циклом 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 []. Вы можете использовать Arrays API, чтобы обойти это, например так:

BaseType[] array = DAO.getArray();
for (SubType subType : Arrays.<SubType>asList(array)) {
    ...
}
1 голос
/ 20 марта 2010

Если вы не неравнодушны к коллекциям 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;
                }
            };
}
1 голос
/ 19 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...