У меня есть проблема с моим собственным кодом JNI на Android 6 (ART). У меня есть метод, который получает экземпляр jclass
и сохраняет эту ссылку класса для будущего использования. Чтобы сделать это, нужно создать ссылку на эту jclass
так, чтобы он не стал недействительным позже:JNI: как проверить, что два экземпляра jclass действительно относятся к одному и тому же классу Java?
std::set<jclass> storedClasses;
void storeClass(jclass cls)
{
TraceLog << "Original jclass:" << cls;
jclass clsRef = (jclass)env.jniEnv()->NewGlobalRef(cls);
TraceLog << "New jclass global reference:" << cls;
storedClasses.insert(clsRef);
}
Проблема заключается в том, что мне нужно хранить только каждый класс раз (отсюда и выбор std::set
для контейнера - это гарантирует, что все элементы уникальны), но NewGlobalRef
фактически создает новое, другое значение jclass
каждый раз. Это имеет смысл, но это было не так до недавнего времени, я полагаю. Я больше не могу использовать это значение (это просто указатель), чтобы обеспечить уникальность.
Как проверить, указывают ли два разных экземпляра jclass
на одни и те же или разные классы Java? Будет ли литье jclass
обратно на jobject
и при вызове java.lang.Object.hashcode
на нем получить нужный результат?
Update: странно, я могу назвать hashcode()
успешно, но всегда возвращается -1
.
Обновление 2:this тоже не работает, все, что я получаю, это java.lang.Class
независимо от того, как я стараюсь.
Спасибо, теперь я понимаю намного больше о JNI! И да, я помню массу ошибок JNI, которые произошли в моем приложении, когда вышла ICS. И тонна удовольствия, которую я их исправил :) –
P. S. Не могли бы вы пояснить, как два разных объекта могут иметь один и тот же хеш-код? Я имею в виду, вы ссылаетесь на вероятностную природу хэшей и на то, что столкновение не является невозможным, или вы имеете в виду, что это действительно может произойти в реальном приложении со статистически значимой вероятностью? –
Если хэш-код вычисляется (например, 'java.lang.String'), два * одинаковых * объекта всегда будут иметь одинаковый хеш. Для простого объекта хэш-код обычно устанавливается на 32-разрядный адрес объекта и «заперт» в первый раз, когда что-то его запрашивает (поэтому он остается неизменным, если объект перемещается). Это позволяет избежать явного сохранения хеш-кода в объектах, которые никогда не хранятся в хэш-контейнерах. В зависимости от характеристик GC может быть вероятным создание объектов в небольшом диапазоне адресов, что делает вероятными столкновения. Я не знаю, как работает ART. – fadden