I have a method that looks like this on Java:
public void myMethod(Object... parms);
But I can't call this method as expected from the scripts.
If, in ruby, I do:
$myObject.myMethod(42);
It gives me org.jruby.exceptions.RaiseException: could not coerce Fixnum to class [Ljava.lang.Object
If I try the following in Javascript:
myObject.myMethod(42);
Then it gives me sun.org.mozilla.javascript.internal.EvaluatorException: Can't find method MyClass.test(number). (#2) in at line number 2
Of course, if I change the signature to take one single object then it works.
I assume that this is because someone along the line does not know how to convert, say Integer to Integer[] with the value at the first position.
I believe something like myMethod({42, 2009}) would work in Ruby, but this seems ugly - I wanted to be able to just do myMethod(42, 2009) to make it less confusing, specially for other languages. Is there any better workaround for this?
Thanks.
Java internally treats the variable-length argument list as an array whose elements are all of the same type. That is the reason why you need to provide an array of objects in your JRuby script.
It works like this:
myMethod [42, 2009].to_java
The to_java method constructs a Java array from a Ruby array. By default, to_java constructs Object arrays as needed in this case. If you need a String array you would use
["a","b","c"].to_java(:string)
More on this at the JRuby wiki
It seems like this is a known bug in jruby. See method dispatch on Java objects / classes should try to find a matching varargs method and NameError thrown when trying to pass argument to a Java method that is defined as having variable length arguments.
According to the link Rhino does support vararg.
Varargs are handled by the compiler as an Object[] which is what the error message describes.
I do not have JRuby experience, but does it work if you have an array argument?
Related
Weak typing in groovy is great and all, but this one has me scratching my head:
myList = new java.util.ArrayList(['foo', 'foo', 'foobar', 'barfoo'])
myList.removeAll('foo')
println myList // prints [foobar, barfoo]
removeAll needs a Collection as a parameter. Docs. Why does line #2 work when I’m sending in a String - Is a groovy String also implicitly a Collection ?
It is rather Groovy provides enhancements to JDK Collection interface one of which is Collection::removeAll(Object[] data) and this allows such behaviour: one element foo seems to be implicitly converted into one-item array as with varargs.
No. Groovy adds an extension method Collection.removeAll(Object[]) that can accept varargs. Your 'foo' gets turned into a single-element array.
In the future, place a breakpoint on methods like this and Step Into; you'll see exactly what value was passed in and whether you are stepping into an extension method or something else unexpected.
why is it mandatory to pass string arg[] as an argument in main method?
why we cannot pass any other data type available in java?
whats the importance of passing String arg[] in main method in java?
History. This is a convention since the days of C, maybe even earlier? Java took most of its syntax from C.
Also, command line arguments are Strings which is why that is the data type. Collections did not exist in Java 1 so they were not an option. Arrays did exist.
Because by passing String arrays, we can pass all the necessary parameters like options/arguments related to the program in the form of String easily. There can be several parameters!
Also, all the other datatypes can be easily converted from String!
An example of calling a program with several parameters therefore resulting in storage of them in String array!
java Sample_Example example1 example2 example3
Arguments:
args[0]=example1
args[1]=example2
args[2]=example3
Here, you are calling Sample_Example Class and passing three parameters example1,example2 and example3 to be used by the program! So, it is always an better alternative to store them in an String array rather than other primitive data-types or in collections or in Wrapper data-types. Always we tend to make our work simpler and here Java makes it simpler for all of us by providing this facility!
The idea is that your Java application will be invoked via a command (whether explicitly entered by a user, implicitly entered (like when you click a shortcut in your OS's GUI), etc).
The String[] refers to the command line arguments specified when your application was invoked.
See Command-Line Arguments in Oracle's Java tutorials for more details.
when we run a java program to command prompt, we can pass some input to our Java program. Those inputs are stored in this String args array.
Because if also we are not passing any argument value while running the main method then also its working fine. It creates an empty string, when we are not passing any values to string arg[]. Where else in case of other data type we have to pass some values.
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.
I am re-learning Java after having an affair with PHP for some years, and I have a question about a convention used in PHP, and how I would accomplish a similar goal in Java...
PHP
function getReport( $options = array() ) {
}
in the above function you would be passing in an optional associative array of options that may look like this
Array(
from => "20110325",
to => "20110413",
subject_id => "2432",
...etc...
);
And if there is no argument passed, it processes fine with no options.
Below is my attempt to form the same function in java, being as it is Strongly typed (which is quite refreshing in some instances) I am having trouble building in the same flexibility. I've considered using a Dictionary but not sure how "best practice" that would be.
public TimeReport getTimeReport(Date from, Date to, int subjectId, int toDoItemId, int filterProjectId, int filterCompanyId) {
}
To call this with one/two/none options it gets pretty ugly with the arguments being...
getTimeReport(null,null,null,234,null,null);
Can you call the getTimeReport with another object used to represent the parameters needed to invoke the getTimeReport function?
Looks like your used to passing strings to functions when you may want to be passing an object.
This kind of flexibility is not built-in to Java, and the language is not very well suited to it in my opinion. You could check each input argument; if null, set it to a default value.
To be more general/didactic, it looks like you are trying to have a Factory of some sort (what class does the method getTimeReport() belong to?). Do you instead want to have the constructor of TimeReport handle these options? Or make different TimeReport constructors for different circumstances?
Usually you would introduce a class representing the configuration parameters for the report generation, like TimeReportSpecification or something.
You can then have static factory methods that give you instances of a TimeReportSpecification, like withToDoItem, so you get:
getTimeReport(TimeReportSpecification.withToDoItem(234));
Say I have a MyClass class in Java, is there a way to check in JNI that a jobject is a MyClass[][]?
My initial idea was to use env->IsInstanceOf(myobj, myArrayClass), but calling env->FindClass("[MyClass") throws a NoClassDefFoundError.
I know this question is old but...
To find a class of your array, use:
env->FindClass("[[Lmy/package/MyClass;")
A little rusty on JNI, but a couple of things:
Call FindClass() on your fully qualified classname, using a "/" as a separator instead of dots. So, for instance if your class is "my.package.MyClass", you would call env->FindClass("my/package/MyClass")
Since you have a two-dimensional array of your object type, you need to call env->GetObjectArrayElement() twice; once to get a row and another time to get a distinct element. Then you can call env->IsInstanceOf() on that element. Make sure you look up the correct signatures for these JNI calls, I've left them as an exercise for the reader :)