I use GWT JSNI to access native JavaScript libraries.

I wonder if it makes any difference in speed which data typ I pass through JSNI.

Example 1:

public static native int test(int value) /*-{
  return this.computeSomething(value);
}-*/;

Example 2:

public static native double test(double value) /*-{
  return this.computeSomething(value);
}-*/;

Assume that computeSomething() takes integer values as an argument and returns an integer value.

  1. Do I have to cast the return value as proposed here: How to work with int values in gwt jsni methods

  2. Does it make any difference in Performance when using int or double for JSNI Functions?

  3. Is there a way to return an int from JSNI? There seems to be a bug here: https://code.google.com/p/google-web-toolkit/issues/detail?id=2693

有帮助吗?

解决方案

When you call into JS from Java, the compiler trusts that the JSNI code follows the method signature exactly. This means that if a double value is returned from an int method, you might get other effects elsewhere. This yields the following results:

  1. Casting is required if you don't trust the JS code to return the correct type. For example, if the method declares an int, but the js code may return a double, you should coerce to an int. Your linked question is more about returning null instead of a number.
  2. In terms of performance it makes no difference at all. Since GWT assumes that the JS will do what you say it will do, it doesn't do any extra work to verify that (except in dev mode, as a way to validate that the code makes sense)

    There are several ways to cast from a JS Number which may be floating point to an integer, so that you can be certain that GWT/Java code can accept it. The first is to simply return a double, and then in your Java code, cast to an int, or use Math.round to remove any unneeded precision. Another is to do in your JSNI what com.google.gwt.dom.client.Element#toInt32 does as of GWT 2.6:

    /**
     * Fast helper method to convert small doubles to 32-bit int.
     *
     * <p>Note: you should be aware that this uses JavaScript rounding and thus
     * does NOT provide the same semantics as <code>int b = (int) someDouble;</code>.
     * In particular, if x is outside the range [-2^31,2^31), then toInt32(x) would return a value
     * equivalent to x modulo 2^32, whereas (int) x would evaluate to either MIN_INT or MAX_INT.
     */
    private static native int toInt32(double val) /*-{
      return val | 0;
    }-*/;
    

    Note the use of | 0 versus || 0 in your linked answer - the first is a bitwise OR, while the second is a boolean OR.

  3. There is no problem returning int from JSNI - the linked issue is about returning java.lang.Integer, the boxed Java type around an int. That issue is flawed, since there is no need for a JsArray<Integer> since com.google.gwt.core.client.JsArrayNumber exists already, you simply must cast to an int to deal with rounding issues.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top