【问题标题】:How to check the type of a value from a JSONObject?如何检查 JSONObject 中的值的类型?
【发布时间】:2013-04-01 23:04:49
【问题描述】:

我正在尝试获取存储在JSONObject 中的值的类型。

String jString = {"a": 1, "b": "str"};
JSONObject jObj = new JSONObject(jString);

是否可以获取key"a"处存储的值的类型; 类似jObj.typeOf("a") = java.lang.Integer

【问题讨论】:

  • 如果您想更好地控制 JSON 解析,请使用 org.json 以外的其他解析器,例如 Jackson。

标签: java json


【解决方案1】:

instanceof 不适合我。在最新版本中动态获取字段的数据类型,而不是使用JSONObject.get,你可以做的是像JsonPrimitive一样得到它

JsonPrimitive value = json.getAsJsonPrimitive('key');

现在你可以打电话了

value.isNumber() value.isBoolean() value.isString()

【讨论】:

  • 如果我们使用JsonObject而不是使用JSONObject,我们可以做上述事情
【解决方案2】:

您可以借助JSONObject.get() 方法从JSON 中获取对象,然后使用instanceof 运算符检查对象的类型。

以下几行:-

String jString = "{\"a\": 1, \"b\": \"str\"}";
JSONObject jObj = new JSONObject(jString);
Object aObj = jObj.get("a");
if (aObj instanceof Integer) {
    // do what you want
}

【讨论】:

  • 注意可能是Integer或者LongFloatDouble.
  • 呵呵,我有一些关于这种情况的神话示例:我有两个相同的 JSONObject {"visits":4880502, ... },但是当我通过 object.get("visits" ) 我有:object1 val: 4880502.0 |类 java.lang.Double object2 val: 4880502 |类 java.lang.Integer
  • gson 有类似的功能吗?他们的文档似乎没有指定有关获取特定字段类型的任何内容。
【解决方案3】:

我发现这种方法可以在 JSON/Json 中查找元素值的数据类型。对我来说效果很好。

JSONObject json = new JSONObject(str);
                Iterator<String> iterator = json.keys();

                if (iterator != null) {
                    while (iterator.hasNext()) {
                        String key = iterator.next();
                        Object value = json.get(key);
                        String dataType = value.getClass().getSimpleName();

                        if (dataType.equalsIgnoreCase("Integer")) {
                            Log.i("Read Json", "Key :" + key + " | type :int | value:" + value);

                        } else if (dataType.equalsIgnoreCase("Long")) {
                            Log.i("Read Json", "Key :" + key + " | type :long | value:" + value);

                        } else if (dataType.equalsIgnoreCase("Float")) {
                            Log.i("Read Json", "Key :" + key + " | type :float | value:" + value);

                        } else if (dataType.equalsIgnoreCase("Double")) {
                            Log.i("Read Json", "Key :" + key + " | type :double | value:" + value);

                        } else if (dataType.equalsIgnoreCase("Boolean")) {
                            Log.i("Read Json", "Key :" + key + " | type :bool | value:" + value);

                        } else if (dataType.equalsIgnoreCase("String")) {
                            Log.i("Read Json", "Key :" + key + " | type :string | value:" + value);

                        }
                    }
                }

【讨论】:

  • 这对我有帮助! String dataType = value.getClass().getSimpleName(); 谢谢!
【解决方案4】:

请注意,JSONObject.get() 可能会以java.lang.Integerjava.lang.Long 的形式返回一个整数,例如我们看到的{a:3,b:100300000000}

D/+++     ( 5526): +++a=>class java.lang.Integer:3
D/+++     ( 5526): +++b=>class java.lang.Long:100300000000

我使用类似的代码(请注意,我们使用类型longdouble 而不是intfloat,并且在我的任务中可能有没有嵌套JSONObjectJSONArray 所以它们不受支持):

    for (String k : new AsIterable<String>(json.keys())) {
            try {
                    Object v = json.get(k);
        //Log.d("+++","+++"+k+"=>"+v.getClass()+":"+v);
                    if (v instanceof Integer || v instanceof Long) {
                            long intToUse = ((Number)v).longValue();
                            ...
                    } else if (v instanceof Boolean) {
                            boolean boolToUse = (Boolean)v).booleanValue();
                            ...
                    } else if (v instanceof Float || v instanceof Double) {
                            double floatToUse = ((Number)v).doubleValue();
                            ...
                    } else if (JSONObject.NULL.equals(v)) {
                            Object nullToUse = null;
                            ...
                    } else {
                            String stringToUse = json.getString(k);
                            ...
                    }
            } catch (JSONException e2) {
                    // TODO Auto-generated catch block
                    Log.d("exc: "+e2);
                    e2.printStackTrace();
            }
    }

其中AsIterable 让我们使用带有迭代器的for(:) 循环并定义为:

public class AsIterable<T> implements Iterable<T> {
    private Iterator<T> iterator;
    public AsIterable(Iterator<T> iterator) {
        this.iterator = iterator;
    }
    public Iterator<T> iterator() {
        return iterator;
    }
}

【讨论】:

  • 为什么String没有被转换成字符串,你又使用getString方法?
【解决方案5】:

最好的解决方案是使用JSONObject.get() 并使用instanceof 运算符检查类型。

【讨论】:

  • 您可以对所需的每种类型使用这种方法,捕获相应的异常
  • 第一种方法,抛出异常,在资源方面有点昂贵,应该避免,尤其是在资源关键设备上使用时。 (移动/标签)
  • @baraky 谢谢你的回答,但我试图避免额外的库。
  • @Ungureanu Liviu 这只是一个错字:)
  • @baraky 啊,我错过了您的编辑:我看到了 GSONObject.get() 版本。对于那个很抱歉。谢谢你:)
【解决方案6】:

您可以将所有数据解析为String,然后尝试将其转换为所需的类型。此时你可能会捕捉到异常并确定解析后的数据是哪种类型。

【讨论】:

    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 2013-07-05
    • 2013-12-25
    • 2020-07-02
    • 1970-01-01
    • 2022-07-08
    • 2016-03-16
    • 2010-09-18
    相关资源
    最近更新 更多