what is the difference between main(String... s) and main(String[] s)? - java

class Test{
public static void main(String... s){
System.out.println("Hello");
}
}
class Test{
public static void main(String[] s){
System.out.println("Hello");
}
}
What is the difference between above two syntax of main() declaration?
Does Java has any special need to have variable length argument?

No difference (when you run the program from the command line, i.e. what the main method is used for). The first variant appeared after Java 5 introduced varargs.
In short, varargs allows you to pass a variable number of arguments to a method. For the method body the arguments are grouped into an array. Like Test.main("foo", "bar") instead of Test.main(new String[] {"foo", "bar"}). The compiler does the array creation for you behind the scene.

The only difference is if you call main directly from other Java code. The first form allows you to write:
Test.main("first", "second", "third");
whereas the second would require you to create an array explicitly:
Test.main(new String[] { "first", "second", "third" });
Personally I don't think I've ever seen the first form used - calling main from other code is pretty rare. There's nothing wrong with it though.

There is no difference.
In general, String... s allows to pass arguments with comma as separator, while the String[] s requires an array.
But in the implementation s is array in both cases. So ... is sintactic sugar in a sense.

Variable number of arguments main(String... s) was only introduced in Java 5.0.

Related

Why can't we just use arrays instead of varargs?

I just came across varargs while learning android(doInBackground(Type... params)) ,SO posts clarified the use of it
My question is why can't we just use Arrays instead of varargs
public void foo(String...strings) { }
I can replace this type of a call by packing my variable number of arguments in an array and passing it to a method such as this
public void foo(String[] alternativeWay){ }
Also does main(String[] args) in java use varargs , if not how are we able to pass runtime parameters to it
Please suggest the benefits or use of varargs and is there there anything else important to know about varargs
The only difference between
foo(String... strings)
and
foo(String[] strings)
is for the calling code. Consider this call:
foo("a", "b");
That's valid with the first declaration of foo, and the compiler will emit code to create an array containing references to "a" and "b" at execution time. It's not valid with the second declaration of foo though, because that doesn't use varargs.
In either case, it's fine for the caller to explicitly create the array:
for(new String[] { "a", "b" }); // Valid for either declaration
Also does main(String[] args) in java use varargs , if not how are we able to pass runtime parameters to it
When it's written as main(String[] args) it doesn't; if you write main(String... args) then it does. It's irrelevant to how the JVM treats it though, because the JVM initialization creates an array with the command line arguments. It would only make a difference if you were writing your own code to invoke main explicitly.
We could use arrays instead of varargs. Varargs are syntactic sugar for using arrays. But they make your code more compact and more readable. Compare
private void foo(String... ss) { ... }
private void bar() {
...
foo("One", "Two", "Three");
...
}
with
private void foo(String[] ss) { ... }
private bar() {
...
foo(new String[] { "One", "Two", "Three" });
...
}
Similarly, we don't need the diamond operator (<>, Java 7) or lambdas (Java 8) either. But they do make code more readable and therefore more maintainable.
One advantage of varargs is for methods requiring at least one parameter, such as max. With varargs you can do it like this
static int max(int first, int... remaining) {
int max = first;
for (int number : remaining)
max = Math.max(max, number);
return max;
}
This is great, because it is impossible to pass no parameters to the max method, and the calling code for max is really clean: max(2, 4, 1, 8, 9). Without varargs the only way to have enforced the condition that at least one number should be passed would have been to have thrown an exception at runtime if the array had length 0 (always best avoided) or to force the caller to write max(2, new int[] {4, 1, 8, 9}) which is really ugly.
Because you function call looks more like a function call, ex.:
new MyAsyncTask().execute("str1", "str2");
looks better than:
new MyAsyncTask().execute(new String[]{"str1", "str2"});
There is no magic behind AsyncTask, very often you dont really need to pass any parameters, sometimes you pass parameters to constructor instead of execute. There are also implementations of AsyncTask :
https://github.com/roboguice/roboguice/blob/master/roboguice/src/main/java/roboguice/util/SafeAsyncTask.java
that dont use varargs at all

Define a String array in Java

In java we can define main() method as both these ways.
public static void main(String[] args) {
System.out.println("Hello World");
}
.
public static void main(String... args) {
System.out.println("Hello World");
}
Both method takes array of String arguments. Now consider following scenario.
String[] arr=new String[10]; // valid
String... arr=new String[10];// invalid
Java never allows to create an array like this wayString... arr=new String[10];. But in above method implementation java allows to do so. My question is how java achieve this two different behavior for two scenarios?
...
is a syntax for method arguments and not for variable definitions. The name of this notation is varargs, which is self explanatory i.e variable number of arguments.
Variable argument or varargs(...) in Java used to write more flexible methods which can accept as many argument as you need not for initialization.
... refers to varargs and its main intention to make method more readable.
void method(String... args) {
}
can be called as
method("a"); OR method("a", "b"); OR method("a", "b", "c");
I see no point in using it in variable declaration, we can't do much with
String... a = {"a", "b"}
An array can anyways be declared with dynamic size
String[] arr = {"a"};
OR
String[] arr = {"a", "b"};
You can use varargs in main because a method declared with varargs (...) is bytecode compatible with a declaration of a method with an array argument (for backwards compatibility). That does not mean that the same syntax is allowed for type declarations.

variations on public static main (String args[])

What is the difference between these 4 method signatures, and why does the 4th not work?
public void main(String args[]) {... }
public void main(String[] args) {... }
public void main(String... args) {... }
public void main(String[] args[]) {... }
The first three are equivalent.* The last one is equivalent to String[][] args (i.e. an array of arrays), which doesn't match what Java requires for main.
However, the idiomatic version is the second one.
* The third one is only valid from Java 5 onwards.
String args[] and String[] args are exactly equivalent. The first form is the "C" form of array declaration, with the [] applied to the variable name. The second form is the preferred Java form, where the [] is (more logically) associated with the type name rather than the variable name. Java allows both forms interchangeably.
The third form appears to be a variable-length parameter list form, though I've never delved into that area.
The forth form is an abomination that only sneaks through the cracks of the spec and should never be used. My guess is that it specifies a 2-dimensional array, but one can't be sure without trying it.
Note that there's nothing sacred about public static main. You can name any method main and call it from anywhere. It's just that when you run a Java program from the command line the JAVA command looks for something of that name (with the usual parameter layout) as the entry point. Up until then main is treated like any other method.

Java array initialization within argument list

How come the first call to someMethod doesn't compile without being explicit that it's String[]?
It's fine to use an array initializer to create a String[] array but you can't use it to pass an argument. Are the curly braces used in some other fashion for passing arguments that derails how I'd expect this to behave?
public void someMethod(String[] arr){
//do some magic
}
public void makeSomeMagic(){
String[] arr = {"cat", "fish", "cow"};
//Does not compile!
someMethod({"cat", "fish", "cow"});
//This compiles!
someMethod(new String[]{"cat", "fish", "cow"});
//This compiles!
someMethod(arr);
}
The compiler error is the following:
The method someMethod(String[]) in the type Moo is not applicable for the arguments (String, String, String)
You can only use the { "hello", "world" } initialization notation when declaring an array variable or in an array creation expression such as new String[] { ... }.
See Section 10.6 Array Initializers in the Java Language Specification:
An array initializer may be specified in a declaration, or as part of an array creation expression (§15.10), creating an array and providing some initial values
If you don't want to use explicit String[], use:
public void someMethod(String... arr){
//do some magic
}
…
someMethod("cm", "applicant", "lead");
The three periods after the final parameter's type indicate that the final argument may be passed as an array or as a sequence of arguments.
Read more.
Or you can use varargs:
public void someMethod(String... arr){
//do some magic
}
public void makeSomeMagic(){
someMethod("cat", "fish", "cow");
}
It's basically a fancy syntax for an array parameter (vararg must be the last parameter in method signature).
You can use the curly braces to initialize an array. In every else case it is used to define blocks of statments.

Is var-args can be used as method argument only?

This is compiling fine :-
public class Demo {
public static void main(String... args) {
}
}
But this is not getting compiled.
public class Demo {
public static void main(String... args) {
String... strVarArgs ;
//here i initiallize strVarArgs by some logic, like we do for arrays
}
}
Plz correct me, if i am syntactically wrong. :-)
cletus wrote :-
It's really just syntactic sugar for an array
Here is an example followed by a statement from a very popular java book written by
Kathy Sierra and Bert Bates (Head First Java, 2nd Edition, McGraw-Hill/Osborne) :-
Topic generics,
<T extends MyClass>, where MyClass is a class, and
<T extends MyInterface>, where MyInterface is an interface.
Following is the as it is copy from book (page 548, chapter 16) :-
In generics, "extends means" "extends or implements"???
The java engineers had to give you a way to put a constraint on a parameterized type, so that you can restrict it to. But you also need to constrain a type to allow only classes that implement a particular interface. So, here's a situation where we need one kind of syntax to work for both situations-inheritence and implementation. In other words, that works for both extends and implementations. And the winning word was ...extends.
Whenever there's a chance for the sun engineer's to reuse an existing keyword, as they did here with "extends", they will usually do that. But sometimes they don't have a choice...(assert, enum).
MyQuestion : Is var-args just a syntactic sugar of array, with no other features then array???
Yes, varargs only applies to function arguments.
It's really just syntactic sugar for an array so instead of:
String... strVarArgs ;
you want
String strVarArgs[];
Example:
public class VargArgsExample {
public static void printArgs(long requiredLongArgument, String... notRequiredStringArray) {
System.out.println(requiredLongArgument);
if (notRequiredStringArray != null) {
for(String arg: notRequiredStringArray) {
System.out.println(arg);
}
}
}
public static void main(String[] args) {
printArgs(1L);
printArgs(1L, "aa");
printArgs(1L, "aa", "bb");
}
}
As you can see this syntax sugar allows us to call methods without specifing varargs argument. If no vararg argument is passed than it is null.
There is no need in just another way of variable declaration, so it is not used for it. And that is why you're getting compile-time error.

Categories