2011-06-23 16 views
5

मुझे लगता है कि मैं इस पर शीर्षक में अधिकांश प्रश्नों को फिट करने में कामयाब रहा हूं!जेएनआई - बेसिक जावा ऑब्जेक्ट्स (बूलियन) को बेसिक जावा ऑब्जेक्ट्स (बूल) का प्रतिनिधित्व करने वाले नौकरी को परिवर्तित करना

मैं अपने देशी सी में जावा से एक वस्तु वापस खींच रहा हूँ ++ कोड:

jclass boolClass = env->FindClass("java/lang/Boolean"); 
if(env->IsInstanceOf(valueObject, boolClass) == JNI_TRUE) { } 
:

jobject valueObject = env->CallObjectMethod(hashMapObject, hashMapGetMID, keyObject); 

यह मुझे वापसी वस्तु मौसम की जाँच करने के लिए संभव है की तरह कुछ का उपयोग कर देशी प्रकारों में से एक है

तो, अब मेरे पास एक नौकरी है जो मुझे पता है कि एक बूलियन है (ऊपरी मामला बी नोट करें) - सवाल यह है कि, इसे बदलने के लिए सबसे प्रभावी तरीका क्या है (मेरे पास पहले से ही मेरे मूल कोड में नौकरी है) एक bool। टाइपकास्टिंग काम नहीं करता है जो समझ में आता है।

हालांकि उपर्युक्त उदाहरण एक बूलियन है, मैं कैरेक्टर-> char, short-> छोटा, इंटीजर-> int, Float-> float, Double-> डबल रूपांतरित करना चाहता हूं।

(एक बार मैं इसे क्रियान्वित किया है मैं इस का जवाब है जो करता है पोस्ट करेंगे Boolean.booleanValue())

+0

क्यों जावा कोड में टाइपकास्टिंग और अनबॉक्सिंग को न केवल संभालते हैं? –

उत्तर

5

आपके पास दो विकल्प हैं।

विकल्प # 1 वह है जो आपने अपने स्वयं के उत्तर में लिखा था: प्रत्येक वर्ग के लिए आदिम मूल्य निकालने के लिए परिभाषित सार्वजनिक विधि का उपयोग करें।

विकल्प # 2 तेज़ है लेकिन कड़ाई से कानूनी नहीं है: सीधे आंतरिक क्षेत्र तक पहुंचें। बूलियन के लिए, वह Boolean.value होगा। प्रत्येक आदिम बॉक्स क्लास के लिए आपके पास "मान" फ़ील्ड के लिए फ़ील्ड आईडी है, और आप सीधे फ़ील्ड को सीधे पढ़ते हैं। (जेएनआई खुशी से इस तथ्य को अनदेखा करता है कि इसे निजी घोषित किया गया है। आप "अंतिम" फ़ील्ड भी लिख सकते हैं और "वास्तव में खराब विचार" श्रेणी में आने वाली अन्य चीजें भी कर सकते हैं।)

"मूल्य" फ़ील्ड का नाम असंभव है बदलने के बाद से serialization तोड़ देगा। इसलिए आधिकारिक तौर पर इसकी अनुशंसा नहीं की जाती है, लेकिन यदि आपको आवश्यकता हो तो अभ्यास में आप इससे दूर हो सकते हैं।

किसी भी तरह से, आपको jmethodID/jfieldID मानों को कैशिंग करना चाहिए, हर बार उन्हें नहीं देख रहा है (लुकअप अपेक्षाकृत महंगे हैं)।

आप IsInstanceof के बजाय कम महंगे IsSameObject फ़ंक्शन का भी उपयोग कर सकते हैं, क्योंकि बॉक्स कक्षाएं "अंतिम" हैं। इसके लिए valueObject क्लास प्राप्त करने के लिए अतिरिक्त GetObjectClass कॉल करने की आवश्यकता है, लेकिन आपको केवल अपनी विभिन्न तुलनाओं से पहले ऐसा करना होगा।

बीटीडब्ल्यू, "char" के उपयोग से सावधान रहें। ऊपर दिए गए आपके उदाहरण में आप एक कॉल (एक 8-बिट मान) पर CallCharMethod (एक 16-बिट यूटीएफ -16 मान) का परिणाम कास्टिंग कर रहे हैं। याद रखें, चार!= jchar (जब तक कि आप किसी भी तरह से विस्तृत वर्णों के लिए कॉन्फ़िगर नहीं किए जाते), लंबा! = jlong ​​(जब तक आप 64-बिट लंबे समय तक संकलित नहीं होते)।

+0

महान उत्तर धन्यवाद! बहुत सारी उपयोगी जानकारी जो मैं सिर्फ सादा नहीं जानता हूं। क्या वहां कोई विशिष्ट संसाधन है जो आप अनुशंसा करते हैं या क्या यह "रक्त, पसीना और आँसू" दृष्टिकोण की कोशिश और परीक्षण किया गया है? :) – Graeme

+2

आप जिन चीजों के बारे में यहां पूछ रहे हैं, वे शायद किसी पुस्तक से नहीं सीखे जा सकते हैं। यदि आपके पास अपना स्वयं का वीएम लिखने का समय है तो आप निश्चित रूप से बहुत कुछ सीखेंगे; अनुपस्थित है कि, बस बहुत सारे कोड लिखें और फिर यह पता लगाने की कोशिश करें कि यह क्यों टूटा हुआ है। :-) – fadden

1

यह समाधान मैं अगर मैं कोई और अधिक इनपुट मिल का उपयोग करने के लिए जा रहा हूँ है। उम्मीद है कि यह मुश्किल नहीं है लेकिन जेएनआई को जानना मुझे लगता है कि यह हो सकता है:

if  (env->IsInstanceOf(valueObject, boolClass)   == JNI_TRUE) 
    { 
     jmethodID booleanValueMID = env->GetMethodID(boolClass, "booleanValue", "()Z"); 
     bool booleanValue   = (bool) env->CallBooleanMethod(valueObject, booleanValueMID); 
     addBoolean(key, booleanValue); 
    } 
    else if(env->IsInstanceOf(valueObject, charClass)   == JNI_TRUE) 
    { 
     jmethodID characterValueMID = env->GetMethodID(charClass, "charValue", "()C"); 
     char characterValue   = (char) env->CallCharMethod(valueObject, characterValueMID); 
     addChar (key, characterValue); 
    } 
0

सामान्य रूप से, मैं बेहतर प्रदर्शन के लिए जेनी लिखता हूं। बेहतर प्रदर्शन कैसे प्राप्त करें? एएसएम, आदिम प्रकार और कुछ विधि कॉल का उपयोग करना। मेरा सुझाव है कि अपने विधि वापसी प्रकार ग में उपयोग कर सकते हैं डिजाइन/C++, इस तरह के jint, jlong, jboolean, jbyte और jchar आदि

अनावश्यक समारोह कॉल के रूप में और अक्षम और unmaintainable कार्यान्वयन कर देगा परिवर्तित।

+0

मैं प्रदर्शन पर गतिशील कोड के लिए जा रहा हूँ। रन टाइम पर मान किसी भी मूल प्रकार के हो सकते हैं - यही कारण है कि मैं जॉबजेक्ट को बूल/char/int इत्यादि में बदलने के लिए सबसे अच्छा तरीका खोजने की कोशिश कर रहा हूं, इसके बिना जांच के और जेएनआई के माध्यम से याद किए बिना। – Graeme

+0

जावा स्तर में गतिशील और लचीला करना बेहतर है। मुझे ऐसा लगता है। – qrtt1

+0

मुझे भी! लेकिन मेरे पास कोई विकल्प नहीं है कि तर्क के कुछ टुकड़े कहाँ किए जाते हैं। – Graeme

संबंधित मुद्दे