2016-02-09 7 views
0

я работаю со следующим классом JAXB иерархии:Java Дженерики - я могу избавиться от сырьевого типа в этом случае использования

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(...) 
public class RecordModifyType extends RecordBaseType 
{ 
    ... 
    public List<FieldModifyType> getField() { ... } 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(...) 
public class RecordAddType extends RecordBaseType 
{ 
    ... 
    public List<FieldAddType> getField() { ... } 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(...) 
public class FieldModifyType extends FieldBaseType 
{ 
    ... 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(...) 
public class FieldAddType extends FieldBaseType 
{ 
    ... 
} 

я наткнулся на метод в другом классе со следующей подписью (обратите внимание на сырые типы):

private void createFields(FTPPartner user, 
          String addressMasterDataID, 
          String connectionMasterDataID, 
          CRTypeEnum crType, 
          List addrFields, 
          List connFields) 

Этот метод вызывается из разных частей класса иногда с List<FieldAddType> в качестве аргументов и другие времена, с List<FieldModifyType>.

Теперь я пытаюсь избавиться от необработанных типов в его подписи.

После get-put principle, я решил изменить подпись

private void createFields(FTPPartner user, 
           String addressMasterDataID, 
           String connectionMasterDataID, 
           CRTypeEnum crType, 
           List<? super FieldBaseType> addrFields, 
           List<? super FieldBaseType> connFields) 
{ 
    ... 
    FieldBaseType someField = new buildField(...); 
    addrFields.add(someField); 
    ... 
} 

... поскольку реализация createFields является только положить вещи в этих коллекциях. Проблема заключается в том, что с RecordModifyType # GetFields() возвращает List<FieldModifyType> и RecordAddType # GetFields() возвращает List<FieldAddType>, я теперь не могу вызвать метод, поскольку он позволяет только для супер типов FieldBaseType, не подтипов:

RecordAddType addrRecord = getRecordAddType(...); 
RecordAddType connRecord = getRecordAddType(...); 
List<FieldAddType> addrFields = addrRecord.getFields(); 
List<FieldAddType> connFields = connRecord.getFields(); 
createFields(user, 
      addressMasterDataID, 
      connectionMasterDataID, 
      crType 
      addFields, // This won't compile 
      connFields); // This won't compile 
marshalRecord(addrRecord); 
marshalRecord(connRecord); 

Использование исходных типов работает как ожидалось - ошибок компиляции и сортировки не существует.

Так что мой вопрос: есть ли способ сохранить поведение, но избавиться от необработанных типов?

+0

Возможно, вы захотите создать небольшой и полный пример, который воспроизводит проблему. Неясно, какая ссылка находится между методом createFields и методами getField ... – assylias

+0

Проблема заключается в api, вы не можете правильно использовать «List », где вы помещаете «FieldBaseType», используя rawtypes, ClassCastException, когда вы извлекаете его в другом классе. Другим решением будет создание нового arraylist для хранения 'FieldBaseType' из списка, возвращаемого' getFields() ' – Ferrybig

+0

. Как бы' createFields() 'решало, добавлять ли экземпляры' FieldAddType' или 'FieldModifyType'? – Thomas

ответ

0

Если я правильно понимаю вашу проблему, компилятор жалуется, потому что не знает, что тип ? super FieldBaseType для вызова - это тот же самый тип для каждого параметра. Кроме того, поскольку оба конкретных типа являются подклассами FieldBaseType, вот как должен быть связан тип IMHO.

Попробуйте ввести метод:

private <T extends FieldBaseType> void createFields(FTPPartner user, 
          String addressMasterDataID, 
          String connectionMasterDataID, 
          CRTypeEnum crType, 
          List<T> addrFields, 
          List<T> connFields) { 
    // during the call, the compiler knows that addrFields and connFields 
    // hold the same type as each other 
} 

Теперь тип выводится в точке вызова.

 Смежные вопросы

  • Нет связанных вопросов^_^