Java and Android inconsistent behavior

I am using a shared library in Android

and in Java

and found this inconsistency in her behavior.

The library depends on org.json.JSONObject

. Which is in a jar contained within the library itself, but it seems that somehow Android is overriding this jar with its own JSON implementation.

When I do this:

    Double a = 0.1;
    JSONObject b = new JSONObject();
    b.put("Hola", a);
    flockSONversionString = b.getString("Hola");

      

In Android

it works without issue, but in Java

it throws an exception because 0.1 is not a string. The second behavior is what I expected from the beginning.

when i do

    Object aObj = b.get("Hola");
    if(aObj instanceof Float){
        System.out.println("Hola is Float");
    } else if (aObj instanceof Long){
        System.out.println("Hola is Long");
    } else if (aObj instanceof Double){
        System.out.println("Hola is Double");
    } else if (aObj instanceof String){
        System.out.println("Hola is String");
    } else {
        System.out.println("Hola has unknown type");
    }

      

In Android

and Java

I get Hola is Double

.

Curiously, if you go to the source code org.json.JSONObject

, the method getString()

will be declared like this:

public String getString(String key) throws JSONException {
    Object object = get(key);
    if (object instanceof String) {
        return (String)object;
    }
    throw new JSONException("JSONObject[" + quote(key) +
        "] not a string.");
}

      

Which seems completely expected because it checks if it is Object

String

and throws an exception if it isn't.

Any idea why this is happening?

Thank!

(I cannot change the dependency on org.json.JSONObject

, as that would break compatibility between Android

and Java

)

+3


source to share


3 answers


Are you sure you are using the same jar in both projects?

Android org.json.JSONObject.toString(String)

is different:

/**
 * Returns the value mapped by {@code name} if it exists, coercing it if
 * necessary, or throws if no such mapping exists.
 *
 * @throws JSONException if no such mapping exists.
 */
public String getString(String name) throws JSONException {
    Object object = get(name);
    String result = JSON.toString(object);
    if (result == null) {
        throw JSON.typeMismatch(name, object, "String");
    }
    return result;
}

      



JSON.toString(Object)

:

static String toString(Object value) {
    if (value instanceof String) {
        return (String) value;
    } else if (value != null) {
        return String.valueOf(value);
    }
    return null;
}

      

In your case, this will not throw an exception on Android.

+1


source


String aString = Double.toString(aDouble);

      



passastring instead of (a);

0


source


For the first part, the android source for getString

 /**
 * Returns the value mapped by {@code name} if it exists, coercing it if
 * necessary, or throws if no such mapping exists.
 *
 * @throws JSONException if no such mapping exists.
 */
public String getString(String name) throws JSONException {
    Object object = get(name);
    String result = JSON.toString(object);
    if (result == null) {
        throw JSON.typeMismatch(name, object, "String");
    }
    return result;
}

      

The important line is here String result = JSON.toString(object);

. Above it gets called get

(the method described below) and it converts your double to a string by calling JSON.toString

(you can go further in the sources to check it)

Now for the second part of the code, when you do get(KEY)

, it will return an object (below is the code for it) and you will have a double, since you put.

 /**
 * Returns the value mapped by {@code name}, or throws if no such mapping exists.
 *
 * @throws JSONException if no such mapping exists.
 */
public Object get(String name) throws JSONException {
    Object result = nameValuePairs.get(name);
    if (result == null) {
        throw new JSONException("No value for " + name);
    }
    return result;
}

      

As a conclusion, these are android use methods for JSONObject, I checked the java sources and it seems that the methods getString

and get

have different logic. I am assuming you compile once for android (with android sdk) and once for java project and this way you have these results.

0


source







All Articles