Multiple object types for varargs in a method prototype?

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.


There is no way to use generics to match two types, eg

public <T extends String | Integer> void myMethod(T... objs); // You can't do this

There is no way in the Java programming language to get it to work so that you can pass an arbitrary number of strings and integers, and have the compiler give an error when you pass something else than a string or integer.