android - support - widget appcompat actionbutton overflow




奇妙な:jniでIntegerの値を変更することはできません (2)

私は整数が変更可能だとは思わない。 それはset方法がないことがわかります。

私は次のように、Cで2つのjava Integerオブジェクトの値を設定するjni関数を記述します:

jni_do_something(JNIEnv *env, jobject thiz, jobject p1, jobject p2) {
    jclass c;
    jfieldID id;
    c = env->FindClass("java/lang/Integer");
    if (c==NULL)
    {
        LOGD("FindClass failed");
        return -1;
    }

    id = env->GetFieldID(c, "value", "I");
    if (id==NULL)
    {
        LOGD("GetFiledID failed");
        return -1;
    }

    env->SetIntField(p1, id, 5);
    env->SetIntField(p2, id, 10);
    return 0;
}

Javaでは、私はこの関数を呼び出しました:

native int do_something(Integer p1, Integer p2);

Integer p1=0, p2=0;
do_something(p1, p2);
Log.d("test", "p1: "+p1);
Log.d("test", "p2: "+p2);

出力は両方とも「10」です、なぜですか?

=========================================

私は多くのテストを行い、以下の点を得ました。 (回答、コメント歓迎)

  1. 私はこのjniネイティブが不変オブジェクトを変更できないとは思わない。 結局、両方のオブジェクトは0から10に変更されます。

  2. オートボクシングにはいくつかの関係があります(はい、わかりません)。 多分、p1とp2はjvmによって特別に処理され、以下のように初期化された場合、単一のオブジェクトを指し示すようになりました。

    整数p1 = 0、p2 = 0;

次の場合:

Integer p1=0, p2=1;

または

Integer p1 = new Integer(0);
Integer p2 = new Integer(0);

結果は正しい(p1:5、p2:10)。 誰かがこれを明確にすることはできますか?

私が言ったことは正しいとは思わないかもしれない。 私はjavaで次のコードを書いています:

Integer a = 0;
Integer b = 0;
b = 10;
Log.d("test", "a: "+a);
Log.d("test", "b: "+b);

それは0,10を出力します。したがって、それらは単一のオブジェクトではありません。 私は本当に混乱しています。


Integer i1 = 500, i2 = 10000;
testInts(i1, i2);
Log.d("log", "I1 = " + i1); 
Log.d("log", "I2 = " + i2);

または

Integer i1 = new Integer(0), i2 = new Integer(0);
testInts(i1, i2);
Log.d("log", "I1 = " + i1); 
Log.d("log", "I2 = " + i2);

出力

I1 = 10
I2 = 10
I1 = 5
I2 = 10
I1 = 5
I2 = 10

Works(あなたの例を使った最初の結果)。 値がバイト(または?)の範囲にあれば、javaはいくつかの奇妙な最適化を使用するということを思い出しました。 EDIT:小さい値のオートボクシングのルールであるようです。

Cコード

    jclass clazz = (*env)->GetObjectClass(env, i1);
    jfieldID mi = (*env)->GetFieldID(env, clazz, "value", "I");

    (*env)->SetIntField(env, i1, mi, 5);
    (*env)->SetIntField(env, i2, mi, 10);
    return 0;




jni