I'm trying to write the prototype of a Java function that can be called with any number of integers and strings:
myMethod(1, 2, 3, "Hello", "World"); // Valid call
myMethod(4, "foo", "bar", "foobar"); // Valid call
Ideally, I would like the ints and strings to be given in any order (and possibly mixed):
myMethod(1, "Hello", 2, "World", 3); // Valid call
I thought of using varargs, but there can be only one in the prototype. Another idea I've had is to use the following prototype:
public void myMethod(Object ... objs) { [...] }
...but I feel that there should be a compilation error in case it is called with something other than the expected types. Of course, a runtime check (instanceof
) could be performed, but that wouldn't be a very elegant solution, would it?
How would you do it?
If you want it to be type safe, I'd go with this:
public myMethod(Thing<?>... thing) { ... }
And then create your Thing classes:
public interface Thing<T> {
public T value();
}
public class IntThing implements Thing<Integer> {
private final int value;
public IntThing(int value) {
this.value = value;
}
public Integer value() {
return value;
}
}
I'll leave it to your imagination to figure out how to write StringThing. Obviously, use a better name than "Thing", but I can't help you with that one.
You then make two static methods:
public static Thing<Integer> thing(int value) {
return new IntThing(value);
}
public static Thing<String> thing(String value) {
return new StringThing(value);
}
Then you wrap each object in a call to thing
:
myMethod(thing(1), thing(2), thing(3), thing("Hello"), thing("World"));
Messy? Yup. Unfortunately, Java doesn't have the capability to hide this stuff away like other languages. Scala's implicit defs would help you here, but that comes with a whole barrel of other problems. Personally, I'd go with the instanceof
checks, but this one will make sure your code is safe at compile-time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With