序列化存储在JavaScriptObject中的非常小的数字

时间:2012-12-07 20:53:35

标签: gwt

我有一个2D数组,我在GWT中表示为JsArray<JsArrayNumber>类型的对象。如果我要将数组转换为Javascript,它看起来像这样:

var test = [[0.6578396255487482,7.875995798E-314,3.1688557021480858E55],
                [9.365832954E-315,0.9866897170404328,9.378991533366766E54],
            [4.999803162025956E51,6.32672779777942E54,1.987536773023561]];

问题在于,当我尝试使用JSONObject.toString()将GWT对象序列化为JSON字符串时,进程挂起并且永远不会完成。通过一些搞乱,我想通过如果我将非常小的数字(以E-315结尾的数字)更改为零,序列化成功完成。为什么GWT对这些数字很难? JSONObject.toString()是序列化这样的东西的正确方法吗?我意识到由于这些数字很小,我可以在序列化之前清理这些对象,但是如果可能的话我宁愿不改变它们,因为它们是一个有点敏感计算的结果。

编辑:

以下是显示行为的示例单元测试:

import org.junit.Test;

import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.junit.client.GWTTestCase;

public class SmallDoubleTest extends GWTTestCase{

    @Test
    public void test(){

        // When the very small numbers are replaced with 0 everything works
        String jsonStr = "[[0.6578396255487482,0,3.1688557021480858E55]," +
                        "[0,0.9866897170404328,9.378991533366766E54]," +
                        "[4.999803162025956E51,6.32672779777942E54,1.987536773023561]]";
        JsArray<JsArrayNumber> jsobj = buildArray(jsonStr);
        System.out.println("First Item: " + jsobj.get(0).get(0));
        System.out.println("Last Item: " + jsobj.get(2).get(2));
        JSONObject jsonobj = new JSONObject(jsobj);
        System.out.println(jsonobj.toString());

        // Putting them back in cause everything to hang on jsonobj.toString();
        jsonStr = "[[0.6578396255487482,7.875995798E-314,3.1688557021480858E55]," +
                         "[9.365832954E-315,0.9866897170404328,9.378991533366766E54]," +
                         "[4.999803162025956E51,6.32672779777942E54,1.987536773023561]]";
        jsobj = buildArray(jsonStr);
        System.out.println("First Item: " + jsobj.get(0).get(0));
        System.out.println("Last Item: " + jsobj.get(2).get(2));
        jsonobj = new JSONObject(jsobj);
        System.out.println(jsonobj.toString());
    }

    public static native JsArray<JsArrayNumber> buildArray(String json) /*-{
        return eval('(' + json + ')');
    }-*/;


    public String getModuleName(){
        return "com.iai.cgs.rest.gwtclient.CGSGWTClient";
    }
}

3 个答案:

答案 0 :(得分:2)

我可能会建议问题在于JSONObject实现,因为它总是尝试从提供的数据手动创建json。我很确定使用本机浏览器JSON.stringify()功能会快得多。例如:

public static native String stringify(JavaScriptObject object)/*-{
   return JSON.stringify(object);
}-*/;

唯一的问题是older browsers(如IE6-7)不支持此功能

答案 1 :(得分:0)

由于JSONArray的JavaDoc已经警告过,如果数组很大,toString()可能需要很长时间(尽管你可能会使用JSONArray,但对于JSON对象,toString可能很昂贵。如果你有一个JsArray,你可以试试<{1}}方法,它也返回一个字符串,只是本机JavaScript,可能更快。

答案 2 :(得分:0)

对于JsArray,您必须使用new JSONArray(jsobj).toString(),而不是JSONObject