オブジェクトの生成
ネイティブコードでもnewに相当することができる.
オブジェクトを生成する関数には,以下がある.
- NewObject
- もっとも簡単で標準的なメソッド生成関数.
- NewObjectA
- NewObjectとの違いは,コンストラクタへの引数をjavalueの配列で渡す点である.
- NewObjectV
- NewObjectとの違いは,コンストラクタへ可変個の引数を渡す点である.
- AllocObject
- オブジェクトのためにメモリを確保,割り付けるが,コンストラクタを実行しない.あとでコンストラクタを呼ぶには,通常のメソッドと同様にして呼ぶ.
- jclassの値
- オブジェクト生成関数がクラスを識別するのに使用する.これで識別されたクラスのインスタンスが生成される.
- jmethodIDの値
- オブジェクト生成関数がコンストラクタを指定するのに使用する.
- 引数の一覧
- コンストラクタが引数を取る場合,ここで引数を指定する.
NewObjectはもっとも簡単で標準的なメソッド生成関数である.
そのネイティブメソッドを以下のクラスで宣言する.
そしてネイティブメソッド.
コメントにあるように,コンストラクタのメソッド名は常に<init>である.また,生成するオブジェクトのjclass値を取得するのを忘れないようにする(実はこれでちょっとハマった).実行結果を以下に示す.
jobject (JNICALL *NewObject)
(JNIEnv *env, jclass clazz, jmethodID methodID, ...);
可変長引数(...)の部分がコンストラクタへの引数の一覧である.NewObjectを使用するサンプルを示す.このサンプルは以下のクラスのコンストラクタをネイティブメソッド内で呼び出す.
instanceof : true comment : Constructed with no parameter instanceof : true comment : Constructed with hoge and 999なお,ここで使用したFindClassはクラス名を示す文字列からjclassを取得する関数である.
jclass (JNICALL *FindClass)
(JNIEnv *env, const char *name);
NewObjectAは,コンストラクタへの引数をjvalueの配列に格納して呼び出す.
先のサンプルとほとんど同じである.次にネイティブメソッド.
上のように,引数のないコンストラクタをNewObjectAで呼ぶときはargsにNULLを指定する.実行結果は先のサンプルと同じである.
jobject (JNICALL *NewObjectA)
(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
jvalueは全てのネイティブ型を格納できる共用体である.
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
NewObjectAを使用するサンプルを示す.このサンプルは先のサンプルと同じSampleObjectをネイティブメソッドの中からNewObjectAを使用して生成するものである.まず,ネイティブメソッドを宣言し呼び出すクラス.
NewObjectVは,コンストラクタへの引数として可変個の引数を指定することができる.
先のサンプルとほとんど同じである.次にネイティブメソッド.
このように,NewObjectVは似たような働きをするオブジェクトを共通化したりするのに便利である.なお,実行結果は先のサンプルと同じである.
jobject (JNICALL *NewObjectV)
(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args);
この関数はネイティブコードでオブジェクト生成のための補助関数を作成するのに便利な関数である.その便利さを示すサンプルを示す.このサンプルは最初のサンプルと同じSampleObjectをネイティブメソッドの中からNewObjectVを使用して生成するものである.まず,ネイティブコードを宣言し,呼び出すクラス.
これまでのNewObject?は,コンストラクタを呼び出してオブジェクトを生成するものであった.このとき,おそらく
先のサンプルとほとんど同じである.次にネイティブメソッド.
このように,AllocObjectを使用する場合は,別途CallVoidMethodでコンストラクタを実行する必要がある.どのような時に使用するのがよいかは良く分からないが,頭の片隅においておいて損はなかろう.
- メモリの割り当て
- コンストラクタによるオブジェクトの初期化
jobject (JNICALL *AllocObject)
(JNIEnv *env, jclass clazz);
これによって返されるjobjectは,初期化されていない.ただ,メモリの割り当てを行なわれただけの状態である.どういうときに使うと有益なのかちょっと思い付かないが,とにかくAllocObjectを使用するサンプルを示す.このサンプルは最初のサンプルと同じSampleObjectをネイティブメソッドの中からAllocObjectとコンストラクタ呼び出しを使用して生成するものである.まず,ネイティブコードを宣言し,呼び出すクラス.

