У меня есть класс, содержащий переменную-член типа long и набор объявлений собственных методов.Я считаю, что память для переменной выделяется в одном из собственных методов, и попытка отмены выделения выполняется в методе finalize () путем вызова другого собственного метода destroy.Я понимаю, что finalize устарела, но прежде чем найти альтернативу для finalize, мне нужно понять, как происходит распределение памяти и как Java и C поддерживают синхронизацию через JNI и как отслеживается эта конкретная переменная-член.Я попытаюсь объяснить сценарий лучше с помощью фрагментов кода:
JSQ.java
class JSQ {
protected long shdl;
protected JSQ() { log("JSQ constructor"); }
protected JSQ(String stmt, boolean isd)
throws DhSQLException
{
// calls a set of native methods
set_shdl();
setstmt(stmt, shdl);
setd(isd, shdl);
prep(shdl);
}
public void finalize()
{
destroy(shdl);
}
private native void set_shdl() throws DhSQLException;
private native void setstmt(String s, long shdl) throws DhSQLException;
private native void setd(boolean b, long shdl);
private native void prep(long shdl) throws DhSQLException;
private native void destroy(long shdl);
protected void execute() throws DhSQLException
{
parExec(shdl);
}
protected native void parExec(long shdl);
}
JSQL.cxx
#define SQ ((sq_stsm_t *)(shdl))
JNIEXPORT void JNICALL Java_com_project_package_JSQ_set_shdl
(JNIEnv *env, jobject obj_This)
{
jclass cls;
jmethodID mid;
cls = (env)->GetObjectClass (obj_This);
mid = (env)->GetMethodID (hThis,"set_JSQ_shdl","(J)V");
status_t status;
// memory allocation
sq_stsm_t * S = new sq_stsm_t(status);
if(status)
{
if (S) { delete S; }
return;
}
// I understand that we're attempting to call a Java method from a native method.
// But which method is it calling?
// Also, are we converting S from sq_stms_t type to jlong?
(env)->CallVoidMethod (obj_This,mid,(jlong) S);
return;
}
JNIEXPORT void JNICALL Java_com_project_package_JSQ_setstmt
(JNIEnv *env, jobject, jstring jstmt, jlong shdl)
{
status_t status;
// cstmt is obtained using jstmt
// Note: #define SQ ((sq_stsm_t *)(shdl))
status = SQ->SetStmt(cstmt);
return;
}
JNIEXPORT void JNICALL Java_com_project_package_JSQ_destroy
(JNIEnv *, jobject, jlong shdl)
{
delete SQ;
}
Точки, в которых я запутался:
Почему long и jlong и преобразование из определенного пользователем типа sq_stsm_t в long.Я понимаю, что Java не знает об этом определяемом пользователем типе.Но почему выбор long?
Почему #define на SQ и как именно уничтожить удаляет память, выделенную в set_shdl, вызывая delete на SQ?
Опубликуйте это, я должен найти замену для финализации - для которой я пришел к выводу, что AutoCloseable с try-with-resources, безусловно, мой лучший вариант.Так как здесь задействовано много местных вызовов, я не понимаю, как мне поступить.Но это отдельный вопрос, и я не хочу вдаваться в подробности.Просто упомяну, чтобы установить некоторый фон для варианта использования.