0

我正在使用以下 jaxb 类层次结构:

@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>as 参数,有时使用List<FieldModifyType>.

现在我正试图摆脱其签名中的原始类型。

遵循get-put 原则,我决定将签名更改为

 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);

使用原始类型按预期工作 - 没有编译错误和编组工作。

所以我的问题是 - 有没有办法保留行为但摆脱原始类型?

4

1 回答 1

0

如果我正确理解您的问题,编译器会抱怨,因为它不知道? super FieldBaseType调用的类型对于每个参数来说都是相同的类型。此外,因为这两种具体类型都是 的子类FieldBaseType,所以恕我直言,这就是需要绑定类型的方式。

尝试输入方法:

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
}

现在在调用点推断类型。

于 2016-02-09T15:53:41.537 回答