Java передается по значению. Вызов func(s)
копирует ссылку s
и передает ее func
, который не может изменить оригинал. null
не является объектом; это особая ссылка. Это означает, что func
не может установить s
в null
, потому что он не может изменить s
, только объект за ним. Просто быть родным методом не дает func
магической силы нарушать правила языка. JNI в основном предназначен для взаимодействия с функциями за пределами языка. Если вы не найдете способ заглянуть в байт-код вызывающего абонента и изменить его кадр стека, вы не сможете этого сделать.
Кроме того, DeleteGlobalRef
не работает таким образом. Он может только освобождать ссылки, сделанные NewGlobalRef
, которые вы можете вызывать для запоминания состояния между вызовами собственных функций. todel
вот локальная ссылка, созданная заново для каждого вызова собственного метода. Я полагаю, вы могли бы DeleteLocalRef
это сделать, но это ничего не даст.
JNIEXPORT void JNICALL
Java_func_test(JNIEnv *env, jobject this, jobject todel)
{
(*env)->DeleteLocalRef(env, todel);
}
Это должно по крайней мере не cra sh, но оно все равно не может изменить ссылку, которую имеет вызывающий; это в основном эквивалент
void func(Object todel) {
todel = null;
}
, который ничего не делает. Опять же: Java копирует ссылку при звонке на func
. Если у вызывающего абонента есть собственная копия ссылки, которую вы пытаетесь удалить, независимо от того, как сильно вы пытаетесь удалить свою копию ссылки, копия вызывающей стороны просто не изменится.
Если вы действительно , действительно хотел, вы можете поместить ссылку в другой объект и изменить это:
public class Box<T> {
public T ref;
public Box() { this(null); }
public Box(T ref) { this.ref = ref; }
public String toString() {
return "Box(" + System.identityHashCode(ref) + ": " + ref + ")";
}
}
<T> void func(Box<T> box) { box.ref = null; }
// as I said; native methods are not magic
// rewriting func with the JNI does not make it more powerful; just more inscrutable
void test() {
var s = new Box<>("this is a new string");
func(s);
System.out.println(s); // "Box(0: null)"
}
но ... зачем вам это?