Suppose I have a code like
public class HelloWorld {
public static String method1(String[] array){return ""+array.length;}
public static String method2(String... array){return ""+array.length;}
public static void main(String args[]) {
System.out.println(method1(new String[]{"test"})); //allowed
//System.out.println(method1("test")); Not allowed
System.out.println(method2(new String[]{"test"})); //allowed
System.out.println(method2("test")); //allowed
}
}
When I do javap HelloWorld
C:\Users\athakur\JavaProjectWorkspace\HelloWorld\bin\test>javap HelloWorld
Compiled from "HelloWorld.java"
public class test.HelloWorld extends java.lang.Object{
public test.HelloWorld();
public static java.lang.String method1(java.lang.String[]);
public static java.lang.String method2(java.lang.String[]);
public static void main(java.lang.String[]);
}
So as per the class file method1 and method2 take same array argument. Then why the difference in the input they can take?
Like method1 cannot take simple String input where as var arg can take variable String inputs as well as array?
So as per the class file method1 and method2 take same array argument.
Yes, except there's extra metadata within the class file to indicate that the parameter for method2 is a varargs parameter. It's really just an extra bit of data on the parameter - that's all.
You can detect it with reflection using Parameter.isVarArgs.
All it means is that the compiler is willing to take a call like this:
method2("test")
and implicitly convert it into
method2(new String[] { "test" })
You don't always want that behaviour, so it has to be explicitly specified on the parameter using the varargs syntax.
I suspect you're also using a slightly old version of javap, if it's not showing you the difference between the two method declarations. On my version (Java 8) I get:
public static java.lang.String method1(java.lang.String[]);
public static java.lang.String method2(java.lang.String...);
The only difference is signature of a method that might have a variable number of arguments, as opposed to an array argument you can pass only one argument. Anyway passing array to a method as vararg is accepted and will be used internally. On the other hand vararg arguments will be converted to an array and used there.
When you pass an array as argument to both method works. To answer you question lets don't use an array
System.out.println(method2("test")); //allowed
System.out.println(method2("test","test2")); //allowed
This works only if you use vararg argument, as you have noticed.
Related
why we not use Object args[] it can also hold any type of data.
class Demo {
public static void main(Object args[]) {
System.out.println("hello");
}
}
The main method receives its arguments from the command line, which in most (all?) OSes is string oriented. In other words, the information that Java will receive to call main, will already be in string form (and only string), so using Object[] for main would require programmers to add explicit casts to String each time they would want to use an argument as a string. Using String[] is therefor more logical, and leads to simpler code.
And of course, as Turing85 said in the comments, the legalistic point of view is that this is "because the JLS says so":
The method main must be declared public, static, and void. It
must specify a formal parameter (ยง8.4.1) whose declared type is array
of String.
Because you cannot pass an object via a command line argument.
I was looking at another post here which was describing what seems to be my problem:
How to make a method which accepts any number of arguments of any type in Java?
However, when I attempted to do this method, when I compiled the program it gave me the error "int cannot be converted to java.util.Objects"
What am I doing wrong?
Code:
public static void clearArray (Objects... args)
{
System.out.println("Error, non character value");
}
How I called the function:
import java.util.Objects;
// Stuff...
clearArray(1);
// Other stuff...
Thank you for checking out my problem!
Look at the signature
public static void clearArray (Objects... args)
That method receivng Objects type and you are passing integer to it. Perhaps changing that to
public static void clearArray (Object... args)
Helps.
You want java.lang.Object, not java.util.Objects.
java.util.Objects is a class with utility methods, not a class you can actually extend and instantiate.
java.lang.Object on the other hand is the superclass of all objects in Java.
And even in a multi-param (varargs) method, the signature needs to be Object ..., not Objects ....
Please clarify my doubt on overriding, When I am calling a method which is not overrided, the method that is being called is form parent class, please give brief explanation on this, The example is like this
public class A {
public void test(int x){
System.out.println("Haiiiiiii");
}
}
public class B extends A{
public void test(Integer x){
System.out.println("hiii Im b's method");
}
}
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
B a=new B();
a.test(2);
}
}
I'm calling b's method but in B class the method takes wrapper class as parameter.
There are 2 methods. One accept int and other accept Integer type. So when you call test() method first it try to find a suitable method without doing any autoboxing. In that case it can find the parent class test() method which accept an int. Therefore java will execute that.
If in case it wouldn't exist then it will try to autobox your parameter and check if there a suitable method. In that case your child class method will get execute.
Edited
Java will always pick the most specific method for a type. Casting/autoboxing/unboxing only when it has to.
If you wanna call child class method you can try
a.test(new Integer(2));
In this case overriding not happen. since overloading when you call it will call the method accept input argument as int.
The compile lets you auto-box and unbox between primitives and wrappers but this doesn't make one a sub-class of the other. int and Integer are two different types hence both of them when used in the method act as two different method (as in your case)
Refer below link for a much clearer explanation
int does not override Integer in Java
I have 2 java class as separate java files say, Class A and Class B
Class A had a method called Method A(1,2) with 2 parameters.
Class A(){
Method A(1,2)
}
Class B creates an object of Class A and try to access Method A with no parameters.
Class B(){
A a = new A()
a.Method A()
}
Is this case possible? If so how can I implement this in Java!
You can define a java method to accept any number of parameters using the "varargs" syntax, for example
public void myMethod(String... s) {
// s is an array String[]
}
If present, a varargs parameter must the last parameter.
These are all valid ways of calling this method:
myMethod(); // in this case the parameter is not null - it's an empty array
myMethod("foo");
myMethod("foo", "bar");
No you cannot call a method with the wrong number of parameters. In fact it shouldn't even compile. Either provide an overload with no parameters or provide default values.
Your option would be to send null values or string literals, or use String ... notation (if the arguments are strings).
Class A(){
Method A(){
return Method A(1,2);
}
Method A(1,2){
...
}
}
add a method with no parameters, which calls the 2 param method with default values.
hope it helps
You obviously can't call methodA() with no args on a classA reference, because classA simply doesn't have methodA() with no arguments.
class WrongOverloading{
void something(String [] a){ .. }
Integer something(String... aaa){ return 1;}
}
Above code does not compile! Compiler says these are duplicate methods.
So using String array or String var-args exactly mean the same?
How are they implemented internally?
They are effectively the same, except the compiler will not accept an varargs unless its the last argument and it won't allow you to pass multiple arguments to an array.
public void methodA(int... ints, int a); // doesn't compile
public void methodA(int[] ints, int a); // compiles
public void methodB(int... ints); // compiles
public void methodC(int[] ints); // compiles
methodB(1); // compiles
methodB(1,2,3,4); // compiles
methodC(1); // doesn't compile
methodC(1,2,3,4); // doesn't compile
From this SO discussion
The underlying type of a variadic method function(Object... args) is
function(Object[] args). Sun added varargs in this manner to preserve
backwards compatibility.
So, as every other answer has said, yes, they're the same.
String... aaa is just like having String[] aaa.
I am assuming that the semicolon after the second function is a typo...
Yes, it's the same.
You can read this article:
It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process.
yes, they are the same because when you call method with elipsis (String...) it converts to String array.
The compiler behind the scenes actually converts your var args method to a method with an array input.
This is the reason why you can have a var args method overloaded with an array as input because after compilation both of them will be identical.
Yes, both are the same ...
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html Just read this site, you will come to know
The [vararg] attribute specifies that the method takes a variable number of parameters. To accomplish this, the last parameter must be a safe array of VARIANT type that contains all the remaining parameters :
[vararg [, optional-attributes]] return-type function-name(
[optional-param-attributes] param-list,
SAFEARRAY(VARIANT) last-param-name);
The varargs syntax basically lets you specify that there are possible parameters, right? They can be there, or cannot be there. That's the purpose of the three dots. When you call the method, you can call it with or without those parameters. This was done to avoid having to pass arrays to the methods.
Have a look at this:
See When do you use varargs in Java?
final public class Main
{
private void show(int []a)
{
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+"\t");
}
}
private void show(Object...a)
{
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+"\t");
}
System.out.println("\nvarargs called");
}
public static void main(String... args)
{
int[]temp=new int[]{1,2,3,4};
Main main=new Main();
main.show(temp);
main.show(); //<-- This is possible.
}
}
It's for this reason, varargs is basically not recommended in overloading of methods.
System.out.printf(); is an example of varargs and defined as follows.
public PrintStream printf(String format, Object ... args)
{
return format(format, args);
}
format - A format string as described in Format string syntax
args - Arguments referenced by the format specifiers in the format string. If there are more arguments than format specifiers, the extra arguments are ignored. The number of arguments is variable and may be zero. The maximum number of arguments is limited by the maximum dimension of a Java array as defined by the Java Virtual Machine Specification. The behaviour on a null argument depends on the conversion.
while calling a method it doesnt care about the return type it will consider the method name , number of parameters and type of parameters and order of parameters .here you are specifying a method with same name same parameters .bcoz in case of var arg if we call method with 2 parameters same method will be executed , if we call method with 3 parameters it will call same method .
here , if we call something(String [] a) and something(String... aaa) same method will be called .bcoz we can replace array with var-arg then a confusion will be arise wich method should be called. then method ambiguity will occour . thats why its showing duplicate method.
here if we pass array to var - arg parameter method it will be executed.internally it converts var - args to single dimensional array.