Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing a return type depending on the calling method

Basically what I want, istwo public methods with slightly different return values to call the same method to do whatever work is needed. They both return the return value of the private method, however the private method will know how to return the correct value depending on the public method that called it.

Example methods:

public Map<Type1, Type3> doSomething1();
public Map<Type2, Type3> doSomething2();

private Map<Type1/Type2, Type3> doSomething(); 

So, in the above example, doSomething() returns either Type1 or Type2 as the Map's key-type, depending on which public method called it. It would be able to perform a simple check, and populate the map with objects of the correct type.

Maybe this can be done through some clever Java reflection? I'm not sure. It all seems pretty dodgy, so if there's a much better way to go about this, I'm all ears.

like image 394
The Dissonant Avatar asked Dec 09 '22 20:12

The Dissonant


2 Answers

I strongly suggest that reflection-mojo should be avoided here. A function must do one thing propertly, and must not depend on who call it.

A better way to do the same would be to refactor doSomething() into smaller functions, create two new functions called doSomethingFor1() and doSomethingFor2(). Both these functions can reuse the refactored parts of the old doSomething().

Now have doSomething1() call and use doSomethingFor1().

Likewise, doSomething2() should use doSomethingFor2().

cheers,

jrh.

like image 94
jrharshath Avatar answered Jan 26 '23 18:01

jrharshath


Please note: I've misunderstood the question, so this answer is opposite of what the question is as asking for. I will leave this up for reference as community wiki, but this does not answer the original question.

If there were a common subtype to Type1 and Type2 called SuperType, then saying that the first type is ? extends SuperType would work.

Here's a little example that uses Integer and Double as the two types, and their common ancestor as Number:

private Map<Integer, String> doSomethingForInteger() {
  HashMap<Integer, String> map = new HashMap<Integer, String>();
  map.put(10, "Hello");
  return map;
}

private Map<Double, String> doSomethingForDouble() {
  HashMap<Double, String> map = new HashMap<Double, String>();
  map.put(3.14, "Apple");
  return map;
}

public Map<? extends Number, String> doSomething(boolean b) {
  if (b)
    return doSomethingForInteger();
  else
    return doSomethingForDouble();
}

Here, the doSomething method will return two types of HashMaps depending on the boolean that is passed in. Either HashMap<Integer, String> or HashMap<Double, String> is returned by the doSomething method.

Actually calling up doSomething with a boolean can be accomplished like this:

Map<? extends Number, String> map1 = doSomething(true);
Map<? extends Number, String> map2 = doSomething(false);

map1 will end up with Hashmap<Integer, String>, while map2 will get Hashmap<Double, String>.

like image 26
2 revs Avatar answered Jan 26 '23 18:01

2 revs