I am working on a method where I’ve written the following line here:
public class XeroTrackingCategoryClient extends TrackingCategoryTransformationClient { public List<ErpListEntry> getCustomFieldListDataByName(String entityCode, String customFieldListName, Boolean fullObject, DateTime lastSyncTime, Boolean isActive) { try { Optional<TrackingCategory> trackingCategory = trackingCategoryTransformationClient.getErpListDataById(entityCode, null, customFieldListName, null).stream().findFirst(); ...cont.
As you can see from the TrackingCategoryTransformationClient
class below, this yields an error as the abstract method getErpListDataById
returns Optional<AccountingObject>
and not Optional<TrackingCategory>
which is what the variable is expecting.
I cannot change the class that is T is bounded by in the generic since other methods depend on it
Instead, I want to know if it’s possible to convert the AccountingObject
object to TrackingCategory
instead?
TrackingCategory
inherits (extends) from AccountingObject
so I tried downcasting by (TrackingCategory)
to the trackingCategoryTransformation class but this gave me an “Inconvertible types” error where AccountingObject cannot be cast to TrackingCategory
Thus, I’m trying to understand what I can do to convert the class to TrackingCategory.
TrackingCategoryTransformationClient
public abstract class TrackingCategoryTransformationClient extends BaseTransformationClient { protected TrackingCategoryTransformationClient(AccountingPackageService accountingPackageService, IHttpHeaderFactory httpHeaderFactory, TransformationConnector transformationConnector, RestTemplate restTemplate) { super(accountingPackageService, httpHeaderFactory, transformationConnector, restTemplate); } public TrackingCategoryTransformationClient(SSLRestTemplate restTemplate, TransformationConnector transformationConnector, WhereClauseBuilderFactory whereClauseBuilderFactory, AccountingPackageService accountingPackageService, IHttpHeaderFactory httpHeaderFactory) { super(accountingPackageService, httpHeaderFactory, transformationConnector, restTemplate); } public abstract <T extends AccountingObject> List<T> getErpListDataById(String entityCode, AccountingObjectType accountingObjectType, String customFieldListName, List<CodeRef> filterList); }
Advertisement
Answer
There are two possible solutions (with TrackingCategory extends AccountingObject
).
The first one is to cast to TrackingCategory
.:
Optional<TrackingCategory> trackingCategory = trackingCategoryTransformationClient .getErpListDataById(entityCode, null, customFieldListName, null) .stream() .filter(TrackingCategory.class::isInstance) .map(TrackingCategory.class::cast) .findFirst();
You can also filter
and map
on Optional
but it would be empty if not the first but the second entry is a TrackingCategory
:
Optional<TrackingCategory> trackingCategory = trackingCategoryTransformationClient .getErpListDataById(entityCode, null, customFieldListName, null) .stream() .findFirst() .filter(TrackingCategory.class::isInstance) .map(TrackingCategory.class::cast);
The second solution is to give the compiler a hint of the generic T
but you should be sure that all elements are TrackingCategory
:
Optional<TrackingCategory> trackingCategory = trackingCategoryTransformationClient .<TrackingCategory> getErpListDataById(entityCode, null, customFieldListName, null) .stream() .findFirst();