Mr. Ree
Mr. Ree

Reputation: 881

How to elegantly wrap overloaded methods in java?

For example, there are some overloaded methods setData(T data) where T can be Something.Builder or Something (there is no common interface implemented by both of them or setData won't accept the common interface as its parameter).

The following code will work but introduce duplicated code.

public void setSomething(Something.Builder data) {
    thirdPartyLib.setData(data);
    ...
    cache = null;
}

public void setSomething(Something data) {
    thirdPartyLib.setData(data);
    ...
    cache = null;
}

Are there any better choices?

For instance, we can merge them into one function template in C++:

template<typename T>
void setSomething(T data) {
    thirdPartyLib.setData(data);
    ...
    cache = null;
}

But how can we do it in java?

Upvotes: 1

Views: 199

Answers (2)

Ralf Kleberhoff
Ralf Kleberhoff

Reputation: 7290

If I understand correctly, thirdPartyLib.setData(data) has (at least) two overloaded versions, one for Something, and one for Something.Builder.

In Java, overloaded methods are completely distinct from one another, just happen to have the same name. You get exactly the same behavior if one is called setSomethingData(Something data), and the other setSomethingBuilderData(Something.Builder data). You can't write down a single call that switches between the two versions at runtime.

So at least for the setData() call, your code needs to have two separate statements. And then I see three approaches:

  • Stay with your duplicated setSomething() methods as given in the question. That's quite ok if it's just a handful of lines common to the two methods.
  • Have two setSomething() methods, but refactor the common parts into some helper method. I'd do that if there's more lines of common code.
  • Have one setSomething(Object data) method that decides internally which setData() version to call, using instanceof tests and casts. I'd avoid that like the plague, as it moves type-checking out of the compile-time into run-time.

After discussing your explicit question, let me ask if you really want to pass builders around instead of "real" objects. That's not what builders were typically meant for.

Upvotes: 1

Vaibhav Singh
Vaibhav Singh

Reputation: 187

You can use generics in that case. Hope this helps


public <T> void setSomething(T data) {
    thirdPartyLib.setData(data);
        ...
        cache = null;

    }

Upvotes: 0

Related Questions