I want to have an abstract function such as
init(int... conditions);
So that inherited classes can have variety of init conditions; may some classes require less number of arugments and may others will take more than the others.
However I wish to rather pass them individually like following
init(arr[0], arr[1], arr[2]... arr[size-1]);
than
init(arr);
Is such approach possible? If not, then should I be better of just passing an array?
Sorry for the confusion that I seem to create.
I have an array of size n that varies.
I cannot hard code passing the argument because the number of arguments is dependable.
I do not want to go for function overload for different versions of init method because that will create about dozen of different versions of init method.
You don't need to overload the method. Just use the so called variable arguments. The are available in Java since version 1.5. For example:
public void init(int... conditions) { ... }
You can use the method in two ways:
Pass the array itself. Like this:
init(array);
Pass each of the array elements. Like this:
init(array[0], array[1], ... array[n]);
Note that if you want to have other arguments for this method, they should be placed in the method signature only before the variable arguments.
You can always use the variable arguments method parameter. In fact it has the same method signature as what you posted above.
public void init(int... conditions){}
This makes conditions an int[], which you can iterate over to get your init conditions.
Related
I'm new to Java and I was wondering under what kind of circumstances should we create a copy of the passed in argument inside the method, and when should we not?
See there could be n number of scenarios where you can make a copy of the arguments before operating upon them, e.g.
Suppose if you want to compare the arguments with final result in method, say if you get a String and in the method make some changes on it and compare for length with passed in argument etc.
In case of exception you want to display/return the actual argument back to calling code.
Similarly there could be a lot of other reasons.
According to my understanding, a method with variable length argument and another method with array as an argument are interchangeable. for eg.
void test(int ... ints){} //method-1
is same as
void test (int [] ints){} //method-2
and we can't use both in the same class (Compile Time Error).
When I use method-1, I can call this method by passing some integers or by passing an array of integers since calling this method using some integers will implicitly create an array of those integers.
For eg.
test(1,2,3); //ok
test(new int[5]); //ok
But,
When I use method-2, I can't call this method by passing some integers as arguments.
test(new int[5]); //ok
test(1,2,3); //NOT OK
Questions:
1) If java implicitly creates an array of the arguments, why it is not able to call test(1,2,3) in case of method-2.
2) Why java doesn't allow using method-1 and method-2 together when both show different behavior?
One difference I could think of is you can have additional arguments to a metod after an int[] but you cant have a variable argument like that. Variable argument should always be the last parameter to a method. Example
void test(int[] a, int a) {} // works fine.
void test(int ... ints, int a){} // compile error.
1) If java implicitly creates an array of the arguments, why it is not
able to call test(1,2,3) in case of method-2.
Because 1,2,3 in test(1,2,3) is not an array, these are three different integers...You have to pass an Array of int to invoke method-2.
2) Why java doesn't allow using method-1 and method-2 together when
both show different behavior?
It creates ambiguity when you call method with array as an argument because array as an argument is allowed in case of varargs as well as array as an argument.
for example, if both method were allowed, test(new int[5]) will create an ambiguity.
The internal representation in the Java compiler of the function declarations in these two cases is identical. That's why the compiler wont let you declare two such functions with the same name.
The difference in the bahivour of these two declarations can be seen when you actually call the functions with the actual arguments. Since Java is a strongly typed language (with strict type checking) it doesn't allow you to pass three integers to the test (int[] a) method.
However, when you call test(int ... a) with test(1,2,3) the compiler generates intermediate code to make a temporary array of three integers and passes it onto the function.
I'm implementing an API an have a method which you pass a list of paths where the program reads resources from
public void importFrom(String... paths) {
}
I'm using varargs to make calling the method as convenient as possible to the user, like so
obj.importFrom("/foo", "/foo/bar);
Is this an appropriate use of varargs? Or is passing in an array better?
In your case varargs is just fine. You don't really need to make an array of the paths that you will be importing because there's nothing you want to do with these paths other than to pass them along to your importFrom method.
The varargs functionality saves you from having to explicitly create an array solely for the purpose of passing a collection of values to a one-off method, which you do appear to have here.
BTW, you can still pass in an array if you want to
public class VarargsDemo {
public static void f(String... args) {
for (String s: args) {
System.out.println(s);
}
}
public static void main(String[] args) {
String[] english = new String[]{"one", "two", "three"};
f(english);
f("uno", "dos", "tres");
}
}
Because the behavior is the same, the difference comes down to a (probably minor) question of what you want the method signature to "say". When you declare a method to take an explicit array parameter, it's almost as if you want to stress that you want to operate on an array object, something that has been defined outside the method and has its own existence and importance outside the method, and one in which, perhaps, operations like indexing matter. When declaring the method with varargs, its as if you are saying "just give me a bunch of items".
Then again, this doesn't have to be true; the JVM doesn't know the difference, all it sees is an array at run time. Many programmers won't bother splitting hairs over the intent of the method signature. Varargs is all about making the calls convenient.
That said, the main limitation of varargs is that such a parameter must be the last one of the method. In your case this is not a problem, but in general it is something to consider.
Since varargs arguments get compiled into a single array argument you could generally prefer varargs since this might be more convinient in some cases and still allows to pass an array in other cases.
public void importFrom(String... paths)
{
}
compiles into
public void importFrom(String[] paths)
{
}
Alternatively you could also use Iterable<String> to make it easier to pass the arguments as collection.
The answer depends on the intended use of your function. If the user typically knows at coding time which arguments he wants to pass in, varargs is the way to go. If the user needs to be able to determine the number of arguments at runtime, an array argument will make life a lot easier for him (or her).
I think the other alternative is to use List<String>. Personally I would use a List if there are more than a few arguments or if arguments are automatically processed from somewhere (parsed from a file for example).
If you will be writing the arguments manually in the code, then I would prefer using the varargs as you proposed.
I have a method that takes 5 double values and performs an action with them. Right now the argument list is five different doubles. Is there any way to pass a double[] as an argument to the method but make sure its length is exactly 5?
One way is this:
private void myMethod(double[] args) {
if (args.length == 5) {
// do something
}
}
but is there a better way?
If you know you need exactly 5 doubles, then I think you are better off asking for 5 distinct doubles. Having them listed out with meaningful names it will still be hard enough (even with intellisense or whatever it's called) to keep the order of the variables straight. If they are in an array, the user will need to consult the documentation to see which value should go in which index.
No. You can't restrict the length of an array passed to a function.
If your goal is to keep the checking code out of the method so it's cleaner, you could delegate the real work to another method.
If your concern is the length of the parameter list you could pass a parameter object.
You could create a class which is a specialization of a Vector limited to 5 doubles, but it seems like overkill. I would just throw an exception if there are too few or too many entries in the array - this is likely a programming problem rather than a runtime exception.
You could put your code in try-catch block. This provides to miss an unnecessary check.
But if something doing wrong you could avoid the problems with exception.
Someone asked me what the difference between the two method parameters and why you would use the ... over specifically assigned array.
putMessage(byte ...send)
putMessage(byte[] send)
I couldn't answer them with confidence and couldn't remember what the ... is called.
The ... in your first example are called varargs. Your second example has an array argument. Varargs are a convenience for times when you want to hard code a variable number of arguments to a method but don't want to manually create an array to hold them. It's a shorthand notation. Consider this:
putMessage(0b00100101, 0b00100101, 0b00100101); // varargs
vs. this:
putMessage(new byte[] { 0b00100101, 0b00100101, 0b00100101 }); // array
The first example is less cluttered and more readable.
The parameters with ellipses are generally referred to as "varargs" if you want to google that.
Using varargs allows you to call a method with variable number of arguments without having to specify an array e.g.
public void printStr(String ...strings) {
for (String s : strings) {
System.out.println(s);
}
}
> printStr("Hello", "World")
Hello
World
So varargs allow a certain degree of convenience, but there are downsides - the varargs parameter must be the last parameter in the method signature, and thus you cannot have more than one varargs parameter to a method. If you want to pass multiple arrays to a method you have to use arrays, not varargs.
Another reason you might see arrays in some places where you might expect varargs is that varargs were only introduced in Java 5 - older code and code that needs to be backwards compatible will still be using arrays even where it might make more sense conceptually to use varargs.
The advantage of using varargs in the method signature is flexibility - there are some situations where the caller will have an array ready anyway and some where they will just have several arguments. Varargs will accept either the array or each variable as a separate argument, saving the caller the trouble of instantiating and populating an array.
The first one is with Varargs.
In short
A. First can be used to call with single byte type arg, 2 byte args.. or many args or an array.
B. second will be used with array only.
The ellipsis (three dots) indicates that you are using "varargs".
See http://download.oracle.com/javase/1,5.0/docs/guide/language/varargs.html for more details.
Inside the method, you access the elements of "send" as an array. The two methods are the same in that regard. The convenience is for the caller. In the second putMessage, the caller is compelled to create an array of bytes to pass to putMessage. In the first putMessage, the caller can simply say "putMessage(byte1, byte2)" or "putMessage(byte1, byte2, byte3)" or "putMessage(byte1)" -- variable number of arguments, or varargs.
The ellipses (...) allow you to inline N parameters of a type to a function call without having to define an array first. In the end you do simply get an array of parameters but it's basically shorthand or syntactic sugar. Also your client code might be a little cleaner and more declarative with the ellipses syntax... though it could easily go the other way and become mucky and unreadable.
Here's a great example of the ellipses syntax (variable length argument lists.) While looking at the sample consider what the client code (in the main function) would look like if an array was used instead of a variable length argument list.