フィールドの設定
ネイティブコードからクラスやオブジェクトのフィールドを設定する.
フィールドの取得と設定の流れはほとんどが同じである.違いは値を設定するための関数である.やはりこの関数はインスタンスフィールドとスタティックフィールドで異なる.インスタンスフィールドの設定には,
jclasやフィールドIDの取得はフィールドの取得の場合と同じである.
void (JNICALL *Set<Type>Field)
(JNIEnv *env, jobject obj, jfieldID fieldID, jint val);
で,スタティックフィールドの設定には,
void (JNICALL *SetStatic<Type>Field)
(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value);
である.例によって<Type>には設定するフィールドの型が入る.具体例はサンプルに示す.フィールドの設定の流れを以下に示す.
| インスタンスフィールドの場合 | スタティックフィールドの場合 |
|---|---|
| 必要があればGetObjectClassでjclassを取得する | |
| GetFieldIDでフィールドIDを取得 | GetStaticFieldIDでフィールドIDを取得 |
| Set<Type>Fieldでフィールドの値を設定 | SetStatic<Type>Fieldでフィールドの値を設定 |
フィールドの取得で使用したサンプルの一部を修正して,フィールドを設定するサンプルを作成する.まず,問題のフィールドを保持するクラスは同じである.
そしてこのクラスのフィールドを設定するJavaクラスを作成する.
このクラスのネイティブメソッドからFieldsのフィールドを設定する.そのネイティブメソッドの実装を以下に示す.まずヘッダ.
そして関数本体.
当然ながら,設定対象となるオブジェクトへの参照を引数にとっている.実行結果を以下に示す.
publicFieldShort = 10 pkgPrivateFieldInt = 20 protectedFieldLong = 30 privateFieldDouble = 40.0 publicStaticFieldBoolean = false pkgPrivateStaticFieldByte = 50 protectedStaticFieldChar = z privateStaticFieldFloat = 60.0SetterのメソッドからFieldsのフィールドが設定できた.
先のサンプルでは,別のオブジェクトにアクセスするネイティブメソッドがある.このサンプルにはJNIの凶暴な一面が含まれている.すなわちネイティブメソッドではフィールドやメソッドのアクセス修飾子に関係なくアクセスできる.Setterのネイティブメソッド内で,引数にとっているFieldsのインスタンスのプライベートメソッドを設定できてしまっている.しかもコンパイル時に警告すら発せられない.この凶暴な一面は常に念頭に置いておかなくてはなるまい.

