3

So lets assume I am having the following stuff defined:

public interface IExportTool {
    void export(IReport iReport);
}

And then attempting to use it:

public class KibanaExporter implements IExportTool{

    public void export(IReport kibana) {
        kibana = (Kibana) kibana;
        ((Kibana) kibana).toJSON();
    }
}

But there are also other classes which would again be doing something like that too:

public class MetricExporter implements IExportTool{

public void export(IReport metric) {
    metric = (Metric) metric;
    ((Metric) metric).toJSON(); // might be something else here like toXML etc
}

}

Please note that both Kibana and Metric are implementing IReport<KibanaRow> and IReport<MetricRow> respectively, while the IReport interface looks like:

public interface IReport<T> {
    void addRow(T row);
}

I don't like all this casting, this doesn't feel right nor gives me autocomplete, so any suggestion how to do it properly?

1
  • 1
    Make IExportTool generic. Then change the class declaration to KibanaExporter implements IExportTool<KibanaRow> and similarly for MetricExporter Commented Jun 22, 2018 at 18:46

1 Answer 1

3

From what you've posted, it's clear that both Kibana and Metric are subtypes of IReport.

In that case, you can make the interface generic:

interface IExportTool<R extends IReport> {
    void export(R iReport);
}

And then change the implementations in this fashion:

public class KibanaExporter implements IExportTool<Kibana>{

    public void export(Kibana kibana) {
        kibana.toJSON();
    }
}

And:

public class MetricExporter implements IExportTool<Metric> {
    public void export(Metric metric) {
        metric.toJSON();
    }
}

This version allows the compiler to understand and validate that only instances of subtypes of IReport will ever be passed to export(). Code using this will be validated by the compiler, such that MetricExporter().export() can only be called with an object of type Metric and KibanaExporter().export() with an object of type Kibana.
And with that, type casts are no longer needed.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! That works.. but I am having a hard time wrapping it around in my head understanding how that all works and why... what is R extends IReport? Any suggestion to read some tutorial on this stuff so I know how to do this on my own next time?
That's the Generics feature. You could check the generics tutirial from Oracle (docs.oracle.com/javase/tutorial/java/generics/why.html), or look at this generics FAQ: angelikalanger.com/GenericsFAQ/FAQSections/…?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.