• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Varargs . . . what are they for?

 
Ranch Hand
Posts: 249
Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Tiger introduces us to something called a vararg. Does this replace the need for overloading methods, so we can pass any variety of parameters, and let the internals of the method sort it out?
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In some sense, although it seems like overloading methods will be more type-safe. I suspect the motivation is to be able to provide printf-like methods. For those of you that are not familiar with C/C++, printf() is the traditionaly C function for printing to standard out (analogous to System.out.println()). An example printf() call looks like

Okay, I obviously made this more complicated than it needs to be. This is obviously a contrived example; I am hoping to avoid many of the details. The first parameter has to be a string (in C, this means a char[], if you want to use a variable. This string can contain any number of format flags that begin with '%'. Each format flag must have a matching parameter in the rest of the arg list. Unfortunately, this means that the number of arguments needed isn't known until run-time. I think this is the key point of using varargs. In contrast, you can still overload methods when you know the number of arguments needed at compile time.
 
Mike Firkser
Ranch Hand
Posts: 249
Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Would the result of your code be "Hello, worlds" with "Hello, world" replacing the "%"?
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, the result would be "Hello, World" which replaces the "%s". The "s" specifies that the corresponding argument should be a string. Other possible format flags are "%d" for int, "%c" for char, and "%f" for float. There are many others, as well as additional arguments for formatting the output. I didn't really want to get into too much detail. The point is that the number of arguments needed isn't known until run-time when the first arg is parsed for the format flags.
 
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To quote "J2SEW 1.5 in a Nutshell" (http://java.sun.com/developer/technicalArticles/releases/j2se15/)

Varargs
The varargs functionality allows multiple arguments to be passed as parameters to methods. It requires the simple ... notation for the method that accepts the argument list and is used to implement the flexible number of arguments required for printf.

void argtest(Object ... args) {
for (int i=0;i <args.length; i++) {
}
}

argtest("test", "data");
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As I mentioned above, the format flag specifies the type of the argument expected. However, this doesn't mean that a compiler error occurs (remember the number of args isn't known until run-time). C doesn't have exceptions, either. I don't even know if the exact behavior is defined by the C standard, but from my experience, a run-time error is not guaranteed. The printf() function simply interpretes the corresponding arg as the expected type. Unfortunately, this can have VERY unexpected results, for example when a char* (a "string") is interpreted as a float. Hopefully, the Java team has put some thought into such issues. I would be interested in seeing what solutions they have come up with.
 
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It would be replacing %s with Hello World. The s after % is for string. With C, when you called printf, you needed to tell it the number and types of its arguments in this way because they could be absolutely anything, and C programs did not have this information at runtime.
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Nicky Bodentien:
It would be replacing %s with Hello World. The s after % is for string. With C, when you called printf, you needed to tell it the number and types of its arguments in this way because they could be absolutely anything, and C programs did not have this information at runtime.



You don't explicitly state the number and types of arguments. These are determined at runtime with the format flags.

I also hope you mean that C programs don't have this information at compile time because they DO have the information at runtime.
 
blacksmith
Posts: 1332
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Layne Lund:

I also hope you mean that C programs don't have this information at compile time because they DO have the information at runtime.

Actually, they do not. Reference types in c are by default simply pointers to a memory location. The memory location typically contains data, but not type information. C programs only get type information at compile time.

I'd like to see an example where one would need actually need varargs to handle something that could not otherwise be handled in Java.
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Re why varargs ... I think we'll quickly find them very natural. Why should functions like max and min compare only two numbers? Why not any number of numbers? x = max(a,b,c,d) It might also be an alternative to overloading a method with optional arguments. I'm looking forward to them!
 
Author
Posts: 253
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mike: I have extended coverage of varargs in my book, but here is a brief synopsis.

Varargs (short for variable-length arguments) simplify the creation of methods that need to take a variable number of arguments. A method that takes a variable number of arguments is called a variable-arity method, or simply a varargs method.

A variable-length argument is specified by three periods (...) and it declares an implicit array of its type. The length of this array is determined by the number arguments passed when the method is called. For example, here is how a method called vaDemo() is written using a vararg.

This syntax tells the compiler that v is a vararg of type int, which means that v is implicitly declared as an array of type int[]. Thus, vaDemo() can be called with zero or more arguments. However, all of the arguments must be of type int, because that is the type of the implicit vararg array. Inside the method, v is accessed using the normal array syntax, or through an enhanced for loop, as shown in the example.

Although the use of a vararg can sometimes eliminate the need to overload a method, they are not designed to replace overloading, per se. Instead, they are designed to simplify cases in which an unknown number of arguments will be passed to a method. (Overloading is generally used to create slightly different versions of a method differentiated by their parameter lists.) Although, the new printf() method, and Formatter class are prime examples that use varargs, their use is not limited to them. Now that the feature exists, it will find other applications.
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Warren Dew:
I'd like to see an example where one would need actually need varargs to handle something that could not otherwise be handled in Java.



Well, as the varargs syntax simply is a shorthand for passing an array, there can't be such an example. Of course that doesn't mean that varargs are worthless - else you could also argue that we don't need Java at all - you could simply program directly in byte code...
 
Ranch Hand
Posts: 116
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Warren Dew:
Layne Lund:

I'd like to see an example where one would need actually need varargs to handle something that could not otherwise be handled in Java.




I tend to agree with Warren here.
I remember reading about Java back in 1997, and a book saying that overloading can solve any problem varargs can.

It must be remembered, that developers like us, do not run the development of the language. It's usaully tool vendors that ask for things like this. I bet IBM, BEA systems or those JBoss peolpe asked for this functionality. I can't honestly see an application developer asking for this varargs feature in Java. I've been programming in Java for 6 years, and never once said to myself, "Hey, I wish I could pass in a variable number of arguments here!"

One more point, will

public static void main(String[] args) {}

now change to something like:

public static void main(String... args) {}

eek!

Jeff Walker
 
Warren Dew
blacksmith
Posts: 1332
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Stan James:

Re why varargs ... I think we'll quickly find them very natural. Why should functions like max and min compare only two numbers? Why not any number of numbers? x = max(a,b,c,d) It might also be an alternative to overloading a method with optional arguments.

I'll accept that as a good example. Packaging stuff into an array is kludgy, I'd agree.

Can you pass in an array if you want? I'm not looking forward to

x = max(a, b, c, d, e, f, g, h, j, k, l, m, n, o, p, q, r, t, s, u, v, w, x, y, z, aa, bb, ab);
 
author
Posts: 799
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jeff Walker:
I've been programming in Java for 6 years, and never once said to myself, "Hey, I wish I could pass in a variable number of arguments here!"



I've never explicitly asked for it, but now that it's there, it seems a natural simplification of syntax. From:

int x = max(new int[] { a, b, c, d });

to:

int x = max(a, b, c, d);

I've had a number of uses for it in the past 9 months.


One more point, will

public static void main(String[] args) {}

now change to something like:

public static void main(String... args) {}



You can do that and it will work the same, but the main reason to declare the ellipses is to allow callers to use varargs. Most of the time you're not going to call your main method directly (except from a test). In any case, why not declare it with the ellipses? Syntactically it's one extra character that gives you a bit more flexibility.

-Jeff-
 
Mike Firkser
Ranch Hand
Posts: 249
Oracle Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe I'm misunderstanding all of this, but it looks like using a vararg is the same thing as passing an array, or vector, or arraylist, etc. Is it somehow more efficient?
 
Jeff Langr
author
Posts: 799
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mike Rutgers:
Maybe I'm misunderstanding all of this, but it looks like using a vararg is the same thing as passing an array, or vector, or arraylist, etc. Is it somehow more efficient?



Not that I'm aware. It's creating an array behind the scenes. It's syntactically more efficient (i.e. less keystrokes).

-j-
 
Jeff Walker
Ranch Hand
Posts: 116
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mike Rutgers:
Maybe I'm misunderstanding all of this, but it looks like using a vararg is the same thing as passing an array, or vector, or arraylist, etc. Is it somehow more efficient?



I must admit, it seems that way to me as well.
It's a language contruct, so that tells me, that the compiler knows in advance, that a predetermined group of, say, strings (to use my main() example a bit more), are going to be passed into the method, at the point the method is called.
If this is indeed true, then it seems to build an array, knowing the number and type of the arguments, and passes that to the method, all with a language syntax sleigh of hand.

So you seem to end up with an array passed in, with all array members of the same type, of course. I see no real advantage here, except simpler syntax.

Further, I would like to know how overloading is supposed to work with a method that already has a variable argument list? Sounds like debugging will be really annoying in this area!

I admit, I know very little about JDK1.5, and I need to read much more about it. I hope nobody miscontrues my intentions, I am only curious, (and I want a copy of the book too! )
Jeff Walker
 
Ranch Hand
Posts: 1923
Scala Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I know varargs from c++.
I didn't miss them in java.

But there where some statements which evoked my disaccord:


The number of arguments to this function is known at compile time. (4)
And the type of argument is known by compile-time. (String, String, int, float)

Bjarne Stroustroup claims in his book 'Design and ... of C++', that the mapping of format-type and type wasn't checked by compilers, which was an argument for him, to introduce cout <<.

(Hey, that's what I'm missing. cout << instead of System.out.println (. Yes - I know, I'm the only one.
Other programers where used to printf and still use it today.)

But the format-type checking, to return to the topic, can be made at compile time.
I didn't recognize this, when reading Stroustrup, but when the first c++-compiler claimed 'parameter mismatch'.

Now when I didn't get the whole thing wrong, you pass in java-varargs a lot of parameters, all of the same type?
The printf function expects arguments of different type.
The function itself cannot know them in advance, but gets the format-string as first argument, and can parse it, and know (in the example above there are three additional parameters, of type String, int, and float.
And a clever compiler can (and will check) them at the place they're generated.

Of course the format-String can be generated at a different place:

But Number (4) and type (String, String, int, float) of arguments are known at compile-time.

Or did you mean not known at compile-time of the printf-function?

[ August 24, 2004: Message edited by: Stefan Wagner ]
[ August 24, 2004: Message edited by: Stefan Wagner ]
 
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Stefan Wagner:
But Number (4) and type (String, String, int, float) of arguments are known at compile-time.


The trick is that the compiler knows the number and type of arguments at each invocation, but the code implementing the printf function itself has no clue about the arguments being passed in, neither at compile nor runtime (via language constructs like args.length).

Instead, printf is given a char array (format string) and a pointer to the rest of the arguments (on the stack). It must parse the format string to determine how to operate on the remaining arguments, but there is no way to enforce that they are in-sync with each other. As mentioned above, the format string could be taken from user input or a file or built somehow such that it didn't even exist at compile time. The compiler therefore cannot enforce it.

The compiler will merrily accept a format string and arguments that will cause all sorts of strangeness. With printf you're less likely to cause trouble -- just bad output. It's scanf (reading into the arguments) that can really hose you.

To achieve C-like varargs, you'd have to box every primitive (wrap ints in Integers, longs with Longs, etc) and pass in an Object array. If autoboxing is included (I don't recall), it means "Object ... args" should always accept any set of arguments.
 
Ranch Hand
Posts: 8945
Firefox Browser Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Read this article on vargs
http://www.onjava.com/pub/a/onjava/excerpt/javaadn_chap5/index.html
 
Stan James
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Can you pass in an array if you want? I'm not looking forward to

x = max(a, b, c, d, e, f, g, h, j, k, l, m, n, o, p, q, r, t, s, u, v, w, x, y, z, aa, bb, ab);



Still better than max(a,max(b,max(c,max(d,max(e, etc))))))))))))) I actually had a four way compare recently and found that syntax really offensive.

I picked max as an example because the REXX language (still a favorite, call it first love syndrome or something) allows any number of arguments to max and min and any of your own functions. I was surprised when I moved to fancy schmancy compiled languages that var args was not supported. I hate having to make life easier for lazy compiler writers

I converted another REXX concept to Java to parse a string into parts. It's really ugly to make an array of parsing criteria. Varargs will be much easier to use even if semantically identical. I'm looking forward to them fer sure.
 
Stefan Wagner
Ranch Hand
Posts: 1923
Scala Postgres Database Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh yes, Pradeep - after reading the oreilly - article, I see a little more clearly now.

I thought I have read somewhere, that you can put mixed types into an ellipsed function, but that's only true, if the method accepts (Object ... foo).
And Object is of specific type.

But one drawback of ellipses is allways overseen!
When I write pseudocode for forums, I used to use the ellipse, to mean 'something outside my actual interest'.

Now it remains of ellipses and might confuse.
 
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Seems dangerous to me.
How will the method know which argument is which? Checking is impossible.
That's why I use a Map to pass variable number of arguments.
The wanted ones are taken out of the Map by name so I can throw a meaningful error if an argument isn't there (or is an incorrect type).
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic