JNI/NDK入門ガイドのjobjectとjclass


JNI/NDK入門ガイドのjobjectとjclass
 前の章JNI/NDK開発ガイドのJavaVMとJNIEnvでは、JavaVMとJNIEnvについて詳しく紹介しました.では、今日の章ではjobjectとjclassの2つの概念を紹介します.
詳しくはjobjectとjclass
JNI開発ではJNI、インスタンスリファレンス(jobject)やクラスリファレンス(jclass)が困惑していますが、少なくとも私が勉強を始めたばかりの頃はそうでした.jobjectとjclassは通常JNI関数の2番目のパラメータとして機能します.Androidソースコードや他の人の関連コードを見ていると、なぜJNIの2番目のパラメータが通常変化しているのか、jobjectがjclassである場合があるのかに気づくかもしれません.これは、JavaクラスにおけるJNI関数に対応する関数の説明を参照してください.Nativeメソッドが静的メソッドであると宣言された場合、対応するパラメータjclassは、静的メソッドがオブジェクトインスタンスに依存せず、クラスに依存するため、パラメータに渡されるのはjclassタイプです.逆に,宣言されたNativeメソッドの場合,非静的メソッドの場合,対応するパラメータはjobjectである.
1.jobjectとjclassはjni.hでの定義
#ifdef __cplusplus
/*
 * Reference types, in C++
 */
class _jobject {};
class _jclass : public _jobject {};
typedef _jobject*       jobject;
typedef _jclass*        jclass;
...
#else /* not __cplusplus */
typedef void*           jobject;
typedef jobject         jclass;

...
#endif /* not __cplusplus */

定義が簡単なので詳しくは言わない.
2.インスタンス参照とクラス参照はJNIの中で関数に体現されている
インスタンス参照とjava.lang.Objectクラスまたはそのサブクラスのインスタンスが対応します.クラスリファレンスとjava.lang.Classインスタンスは、クラスのタイプを表します.GetFieldIDのような動作では、パラメータjclassが必要であり、クラスの動作であり、クラスからfieldの記述が得られるためである.これに対してGetIntFieldは、このインスタンスからこのfieldの値が得られるため、パラメータjobjectを必要とします.すべてのJNIメソッドでjobjectとインスタンス操作の結合とjclassとクラス操作の結合は一致している.したがって、クラス操作とインスタンス操作の違いは容易に覚えられます.上述したことは、JNIにおいて以下のように関数として表すことができる.
	//            ,      jclass
    jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
    jobject     (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
    jobject     (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);

	//              ,      jobject
	jobject     (*GetObjectField)(JNIEnv*, jobject, jfieldID);
	jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
	object     (*GetObjectField)(JNIEnv*, jobject, jfieldID);
	

3.静的メソッドとインスタンスメソッドの違いを簡単に説明します.
静的メソッドは、静的変数と同様に、そのクラスのオブジェクトではなくクラス自体に属します.staticとして定義されたメソッドを呼び出すには、その前にクラスの名前を付けるか、非静的メソッドを呼び出すようにクラスオブジェクトを介して呼び出すことができます.インスタンスメソッドは、クラスのインスタンスで使用する必要があります.インスタンスメソッドでは、クラスの非静的メンバーを使用するか、クラスの静的メンバーを使用することができます.クラスの静的メソッドで、静的変数はクラスのマウント時にマウントされます.ただし、クラスの静的変数は、クラスのオブジェクトが共有するもの、すなわち、すべてのオブジェクトが変数を共有するものであることに特に注意してください.静的変数はできるだけ少なくすることをお勧めします.内部変数はできるだけ静的メソッドで使用します.
ここでstaticキーワードは静的を表す.静的メソッドを宣言する構文は、staticがタイプメソッド名(パラメータリスト){//メソッドボディ}を返す
静的メソッドとインスタンスメソッドが唯一異なるのは、静的メソッドがタイプを返す前にstaticキーワードを追加することです.静的メソッドの呼び出しには,(1)クラスのインスタンスオブジェクトを介して呼び出す呼び出しフォーマットがオブジェクト名である.メソッド名(2)クラス名による呼び出しフォーマット:クラス名::メソッド名
4.実例分析
前の章を通じて、読者の皆さんはきっとjobjectとjclassに対してはっきりした認識を持っていると思います.以下、実際のcodeで例を挙げて説明します.Javaエンドコード:
public class Jobject_Jclass {
    public native static void fun();//   
    public native void fun1();//    
}

JNIエンドコード:javahコマンドでヘッダファイルを生成します.生成されたヘッダファイルは以下の通りです.ここの2番目のパラメータに注意してください.あなたは本当にそうだったことに気づきます.私をいじめません.
/*
 * Class:     com_xxx_api_binder_Jobject_Jclass
 * Method:    fun
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_xxx_api_binder_Jobject_1Jclass_fun
  (JNIEnv *, jclass);

/*
 * Class:     com_xxx_api_binder_Jobject_Jclass
 * Method:    fun1
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_xxx_api_binder_Jobject_1Jclass_fun1
  (JNIEnv *, jobject);
は最後に書きました.jobjectとjclassについてはここで一段落します.Javaで定義されたnativeメソッドが静的メソッドである場合、2番目のパラメータはjclassであり、jclassはnativeメソッドが属するクラスのclass自体を表す.Javaで定義されたnativeメソッドが非静的メソッドである場合、2番目のパラメータはjobjectであり、jobjectはnativeメソッドが属するクラスのインスタンスオブジェクトを表す.最後に質問が残っています.jclassとjobjectは互いに変換できますか.もし変換できるなら、具体的にはどんな方法で変換できますか.