В java, что делает частный статический метод registerNatives()
класса Object?
Что делает метод registerNatives()?
Ответ 1
Другие ответы технически правильны, но не очень полезны для тех, у кого нет опыта JNI.: -)
Обычно для того, чтобы JVM мог найти ваши собственные функции, их нужно назвать определенным образом. например, для java.lang.Object.registerNatives
, соответствующая функция C называется Java_java_lang_Object_registerNatives
. Используя registerNatives
(вернее, функцию JNI registerNatives
), вы можете называть свои функции C тем, что вы хотите.
Здесь соответствующий C-код (из OpenJDK 6):
static JNINativeMethod methods[] = {
{"hashCode", "()I", (void *)&JVM_IHashCode},
{"wait", "(J)V", (void *)&JVM_MonitorWait},
{"notify", "()V", (void *)&JVM_MonitorNotify},
{"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
{"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
};
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
{
(*env)->RegisterNatives(env, cls,
methods, sizeof(methods)/sizeof(methods[0]));
}
(Обратите внимание, что Object.getClass
отсутствует в списке, он все равно будет вызываться "стандартным" именем Java_java_lang_Object_getClass
.) Для перечисленных функций соответствующие функции C указаны в этой таблице, что чем писать кучу функций переадресации.
Регистрация собственных функций также полезна, если вы встраиваете Java в свою C-программу и хотите связать себя с функциями внутри самого приложения (в отличие от общей библиотеки), или используемые функции не иначе "экспортируются", так как они обычно не будут найдены стандартным механизмом поиска метода. Регистрация собственных функций также может быть использована для "повторной привязки" собственного метода к другой функции C (полезно, если ваша программа поддерживает динамическую загрузку и выгрузку модулей, например).
Я призываю всех прочитать книгу JNI, в которой говорится об этом и многом другом.: -)
Ответ 2
Что может быть немного запутанным, так это то, что код, показанный для java.lang.Object.registerNatives
в предыдущем ответе, является просто примером регистрации собственных функций. Это код, который (в реализации OpenJDK) регистрирует собственные функции для класса Object. Чтобы зарегистрировать собственные функции для своего собственного класса, вы должны вызвать функцию JNI RegisterNatives
из собственного кода в вашей собственной библиотеке. Это может показаться немного круговым, но есть несколько способов разбить цикл.
-
Следуйте примеру этой реализации класса Object:
а. В вашем классе Java объявите собственный метод (желательно статический) с именем
RegisterNatives
(или любым другим именем, это не имеет значения).б. В вашем собственном коде определите функцию с именем
Java_<your fully qualified class name>_registerNatives
, которая содержит вызов функции JNIRegisterNatives
.с. Убедитесь, что в вашем Java-коде метод Java
RegisterNatives
вызывается перед любыми вызовами других собственных методов.
ИЛИ
-
Используйте
JNI_OnLoad
а. В вашей собственной библиотеке определите функцию
jint JNI_OnLoad(JavaVM *vm, void *reserved)
. В теле этой функции вызовите функцию JNIRegisterNatives
.б. Java VM автоматически ищет и вызывает
JNI_OnLoad
, когда ваша родная библиотека загружаетсяSystem.loadLibrary
, которую вы уже должны вызывать, возможно, в статическом инициализаторе для вашего класса. (Вы получаете требуемый указательenv
, вызывая функциюGetEnv
в таблице, на которую указывает указательvm
.)
Ответ 3
Поскольку вы искали исходный код, чтобы его найти, довольно легко догадаться, не так ли?
Это собственный метод, и он называется registerNatives, поэтому я предполагаю, что он регистрирует объекты с базовой платформой.
Он также закрыт, поэтому его, вероятно, не беспокоит.