I'm working with the following jaxb class hierarchy:
@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
{
...
}
I stumbled upon a method in some other class with the following signature ( please note the raw types ):
private void createFields(FTPPartner user,
String addressMasterDataID,
String connectionMasterDataID,
CRTypeEnum crType,
List addrFields,
List connFields)
This method is called from different parts of the class sometimes with List<FieldAddType>
as arguments and other times with List<FieldModifyType>
.
Now I'm trying to get rid of the raw types in its signature.
Following the get-put principle , I decided to change the signature to
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);
...
}
... since the createFields implementation is only putting stuff in these collections. The problem is that since RecordModifyType#getFields() returns List<FieldModifyType>
and RecordAddType#getFields() returns List<FieldAddType>
, I now can not invoke the method, since it only allows for super types of FieldBaseType, not subtypes:
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);
Using raw types is working as expected - there are no compile errors and marshalling works.
So my question is - is there a way to preserve the behaviour but get rid of the raw types?
If I understand your problem correctly, the compiler is complaining because it doesn't know that the type ? super FieldBaseType
? super FieldBaseType
for the call is the the same type for each parameter. Also, because both concrete types are subclasses of FieldBaseType
, that's how the type needs to be bound IMHO.
Try typing the method:
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
}
Now the type is inferred at the call point.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.