42

In my Java code I often use the very handy method(Class... args) varargs. As far as I know, they allow you to pass any amount of Class objects or an array of Class[]. Since I also often use the Java collection classes, I am frustrated by the lack of compatibility between both. As a result, I end up doing collection.toArray(), but that has some type safety issues.

So now for the question: why doesn't Java allow instances of Iterable<T> as vararg arguments, as long as the generic type fits the T... type of the vararg? Doesn't everyone use lists, sets, etc. all the time? Is there an easy, type-safe way to provide the conversion from collection to vararg?

Joachim Sauer
  • 278,207
  • 54
  • 523
  • 586
tb189
  • 1,842
  • 3
  • 20
  • 34

1 Answers1

51

The reason is simple: a variable arity parameter is simply an old-school array paramater with some additional metadata that tells the compiler to provide some syntactic sugar (namely, it allows implicit array creation).

So from the perspective of the JVM Object... is pretty much the same as Object[]. Allowing collections as well would require a more invasive change to the JVM (which has no explicit support for collections to date).

Note that if you want to support both ways, then making the collection-based method is probably the better approach:

public void frobnicate(Object... args) {
  frobnicate(Arrays.asList(args));
}

public void frobnicate(Iterable<Object> args) {
  // do stuff
}

The reason for this is that using Arrays.asList() is usually a cheaper operation than Collection.toArray() (because it creates a simple wrapper).

Joachim Sauer
  • 278,207
  • 54
  • 523
  • 586
  • It answers the question from a technical point of view, but as a developer, I still think it's silly to supply a helper method whenever I want to use both collections and plain objects. Of course, the fact that we have collections and varargs is already a relief compared to some years ago. – tb189 Aug 01 '11 at 13:02
  • 3
    @The Elite Gentleman: I just prefer using `frobnicate` over a simple `foo`. [source](http://www.catb.org/jargon/html/F/frobnicate.html). – Joachim Sauer Aug 01 '11 at 13:11
  • @tb189: why a "helper method"? You want a method to accept two different, type-wise unrelated kinds of arguments. That's *exactly* the problem that overloading is designed to handle. – Joachim Sauer Aug 01 '11 at 13:13
  • @Jaochim Sauer: Of course, and I agree in case the overloading method actually does something conceptually (e.g. double -> int = rounding, String -> int = parsing with possible errors). In this case, however, as a user of the language (not a technical expert), I feel arrays and collections are the same things functionally, and converting them could be done behind the screens. – tb189 Aug 01 '11 at 13:20
  • @tb189: and that's where I disagree: they are **not** the same thing. In **my** opinion, arrays are a low-level implementation detail that a normal developer shouldn't care about. *Everything* that is "more than 1 of something" should be a collection. Just because *internally* collections and varargs use arrays doesn't mean that business code should use them as well. – Joachim Sauer Aug 01 '11 at 13:23
  • @The Elite Gentleman: frobnication is what happens when two paramaters mate. – Stephen C Aug 01 '11 at 13:57