Home > OS >  How to convert a class A to class B?
How to convert a class A to class B?

Time:07-14

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

CodePudding user response:

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();
  • Related