java - जावा में मूल कीवर्ड क्या है?




jni native keyword (11)

यह एक विधि को चिह्नित करता है, यह जावा में नहीं, अन्य भाषाओं में लागू किया जाएगा। यह जेएनआई (जावा मूल इंटरफ़ेस) के साथ मिलकर काम करता है।

प्रदर्शन के महत्वपूर्ण वर्गों को लिखने के लिए अतीत में मूल विधियों का उपयोग किया गया था, लेकिन जावा के साथ तेजी से यह अब कम आम है। वर्तमान में मूल तरीकों की आवश्यकता होती है

  • आपको जावा से लाइब्रेरी कॉल करने की आवश्यकता है जो अन्य भाषा में लिखी गई है।

  • आपको सिस्टम या हार्डवेयर संसाधनों तक पहुंचने की आवश्यकता है जो केवल दूसरी भाषा (आमतौर पर सी) से पहुंच योग्य हैं। असल में, वास्तविक सिस्टम (डिस्क और नेटवर्क आईओ, उदाहरण के लिए) के साथ बातचीत करने वाले कई सिस्टम फ़ंक्शन केवल ऐसा ही कर सकते हैं क्योंकि वे देशी कोड को कॉल करते हैं।

जावा मूल इंटरफ़ेस विशिष्टता भी देखें

इस पहेली को खेलते समय (यह एक जावा कीवर्ड ट्रिविया गेम है), मैं native कीवर्ड में आया था।

जावा में मूल कीवर्ड क्या है?


  • native जावा में एक कीवर्ड है, यह प्लेटफॉर्म पर निर्भर करता है।
  • native विधियां जावा ( जेएनआई ) और अन्य प्रोग्रामिंग भाषाओं के बीच इंटरफ़ेस के रूप में कार्य करती हैं।

चीज़ों को स्पष्ट करने के लिए न्यूनतम उदाहरण :

मुख्य.जावा :

public class Main {
    public native int square(int i);
    public static void main(String[] args) {
        System.loadLibrary("Main");
        System.out.println(new Main().square(2));
    }
}

मुख्य.c :

#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_square(
    JNIEnv *env, jobject obj, jint i) {
  return i * i;
}

संकलित और चलाएं :

sudo apt-get install build-essential openjdk-7-jdk
export JAVA_HOME='/usr/lib/jvm/java-7-openjdk-amd64'
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
  -I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main

आउटपुट :

4

उबंटू 14.04 एएमडी 64 पर परीक्षण किया गया। ओरेकल जेडीके 1.8.0_45 के साथ भी काम किया।

आपके साथ खेलने के लिए गिटहब पर उदाहरण

जावा पैकेज / फ़ाइल नामों में अंडरस्कोर सी फंक्शन नाम में _1 बच जाना चाहिए जैसा कि यहां बताया गया है: अंडरस्कोर युक्त एंड्रॉइड पैकेज नाम में जेएनआई फ़ंक्शंस को आमंत्रित करना

व्याख्या :

यह आपको अनुमति देता है:

  • जावा से मनमाने ढंग से असेंबली कोड के साथ संकलित गतिशील रूप से लोड की गई लाइब्रेरी (यहां सी में लिखी गई) को कॉल करें
  • और जावा में परिणाम वापस प्राप्त करें

इसका उपयोग इस प्रकार किया जा सकता है:

  • बेहतर सीपीयू असेंबली निर्देशों के साथ एक महत्वपूर्ण खंड पर तेज़ कोड लिखें (सीपीयू पोर्टेबल नहीं)
  • प्रत्यक्ष सिस्टम कॉल करें (ओएस पोर्टेबल नहीं)

कम पोर्टेबिलिटी के व्यापार के साथ।

जावा से जावा को कॉल करना भी आपके लिए संभव है, लेकिन आपको पहले सी में एक जेवीएम बनाना होगा: सी ++ से जावा फ़ंक्शंस को कैसे कॉल करें?

एंड्रॉइड एनडीके

अवधारणा इस संदर्भ में सटीक है, सिवाय इसके कि आपको इसे स्थापित करने के लिए एंड्रॉइड बॉयलरप्लेट का उपयोग करना होगा।

आधिकारिक एनडीके भंडार में "कैनोलिक" उदाहरण हैं जैसे हैलो-जेनी ऐप:

आप एंड्रॉइड ओ पर lib/arm64-v8a/libnative-lib.solib/arm64-v8a/libnative-lib.so करते हैं, तो आप प्री-संकलित देख सकते हैं। .so यह lib/arm64-v8a/libnative-lib.so के अंतर्गत मूल कोड से मेल lib/arm64-v8a/libnative-lib.so

TODO पुष्टि करें: इसके अलावा, file /data/app/com.android.appname-*/oat/arm64/base.odex कहता है कि यह एक साझा लाइब्रेरी है, जो मुझे लगता है कि file /data/app/com.android.appname-*/oat/arm64/base.odex जावा फाइलों के अनुरूप एआरटी में है , यह भी देखें: एंड्रॉइड में ओडीईएक्स फाइलें क्या हैं? तो शायद जावा वास्तव में native इंटरफ़ेस के माध्यम से भी चलाया जा सकता native ?

ओपनजेडीके 8 में उदाहरण

आइए देखें कि Object#clone को jdk8u60-b27 में परिभाषित किया गया है।

हम निष्कर्ष निकालेंगे कि इसे native कॉल के साथ लागू किया गया native

सबसे पहले हम पाते हैं:

find . -name Object.java

जो हमें jdk/src/share/classes/java/lang/Object.java#l212 :

protected native Object clone() throws CloneNotSupportedException;

अब मुश्किल भाग आता है, यह पता लगाने के लिए कि सभी संकेतों के बीच क्लोन कहाँ है। जिस प्रश्न ने मेरी मदद की वह थी:

find . -iname object.c

जो सी या सी ++ फाइलें पाएंगे जो ऑब्जेक्ट के मूल तरीकों को लागू कर सकते हैं। यह हमें jdk/share/native/java/lang/Object.c#l47 :

static JNINativeMethod methods[] = {
    ...
    {"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]));
}

जो हमें JVM_Clone प्रतीक पर ले जाता है:

grep -R JVM_Clone

जो हमें hotspot/src/share/vm/prims/jvm.cpp#l580 :

JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
    JVMWrapper("JVM_Clone");

मैक्रोज़ का एक समूह विस्तार करने के बाद, हम निष्कर्ष पर आते हैं कि यह परिभाषा बिंदु है।


मूल कीवर्ड को यह इंगित करने के लिए एक विधि पर लागू किया जाता है कि विधि जेएनआई (जावा मूल इंटरफ़ेस) का उपयोग करके मूल कोड में लागू की गई है । मूल एक संशोधक केवल विधियों के लिए लागू होता है और हम इसे कहीं और लागू नहीं कर सकते हैं । सी, सी ++ में लागू विधियों को मूल विधियों या विदेशी तरीकों के रूप में जाना जाता है।

मूल कीवर्ड का मुख्य उद्देश्य हैं:

  • सिस्टम के प्रदर्शन में सुधार करने के लिए।
  • मिशन स्तर / मेमोरी स्तर संचार प्राप्त करने के लिए।
  • पहले से ही मौजूदा विरासत गैर जावा कोड का उपयोग करने के लिए।

नेटिव गैर पहुंच संशोधक है। इसे केवल METHOD पर लागू किया जा सकता है। यह विधि या कोड के प्लेटफॉर्म-निर्भर प्रत्यारोपण को इंगित करता है।


मूल जावा में एक कीवर्ड है, जिसका प्रयोग अनुपूरक संरचना (विधि) को अमूर्त के रूप में करने के लिए किया जाता है, लेकिन यह एक प्लेटफॉर्म पर निर्भर होगा जैसे देशी कोड और मूल स्टैक से जावा स्टैक से निष्पादित करना।


native कीवर्ड को यह इंगित करने के लिए एक विधि पर लागू किया जाता है कि विधि जेएनआई (जावा मूल इंटरफ़ेस) का उपयोग करके मूल कोड में लागू की गई है।


मूल कीवर्ड का उपयोग प्लेटफॉर्म-निर्भर कोड जैसे सी या सी ++ में लागू किया गया एक तरीका घोषित करने के लिए किया जाता है। जब किसी विधि को देशी के रूप में चिह्नित किया जाता है, तो उसके पास शरीर नहीं हो सकता है और इसके बजाय अर्धविराम के साथ समाप्त होना चाहिए। जावा नेटिव इंटरफेस (जेएनआई) विनिर्देश देशी विधियों को लागू करने के लिए नियमों और दिशानिर्देशों को नियंत्रित करता है, जैसे कि जावा और मूल अनुप्रयोग के बीच डेटा प्रकार रूपांतरण।

निम्नलिखित उदाहरण क्लासिक के रूप में घोषित विधि के साथ एक वर्ग दिखाता है:

public class NativeExample {
    public native void fastCopyFile(String sourceFile, String destFile);
}

Nativ e कीवर्ड का उपयोग प्लेटफॉर्म-निर्भर कोड जैसे सी या सी ++ में लागू किया गया एक तरीका घोषित करने के लिए किया जाता है। जब किसी विधि को देशी के रूप में चिह्नित किया जाता है, तो उसके पास शरीर नहीं हो सकता है और इसके बजाय अर्धविराम के साथ समाप्त होना चाहिए। जावा नेटिव इंटरफेस (जेएनआई) विनिर्देश देशी विधियों को लागू करने के लिए नियमों और दिशानिर्देशों को नियंत्रित करता है, जैसे कि जावा और मूल अनुप्रयोग के बीच डेटा प्रकार रूपांतरण।

निम्नलिखित उदाहरण एक वर्ग को देशी के रूप में घोषित विधि के साथ दिखाता है

public class NativeExample {

public native void fastCopyFile(String sourceFile, String destFile);

}

देशी तरीकों के नुकसान:

  • विंडोज़ में डीएलएल (गतिशील लिंक लाइब्रेरी) फ़ाइल एक्सटेंशन के साथ मूल विधियों को संग्रहीत किया जाता है। डीएलएल फाइलें मशीन निर्भर हैं। इस प्रकार, मूल विधियां पोर्टेबल नहीं हैं।

  • चूंकि देशी विधियां मशीन कोड का उपयोग करती हैं, इसलिए इससे गंभीर सुरक्षा समस्याएं हो सकती हैं।


मूल कोड को लागू करने वाले कार्यों को देशी घोषित किया जाता है।

जावा नेटिव इंटरफेस (जेएनआई) एक प्रोग्रामिंग फ्रेमवर्क है जो जावा वर्चुअल मशीन (जेवीएम) में कॉल करने के लिए जावा कोड को सक्षम करता है, और मूल अनुप्रयोगों (हार्डवेयर और ऑपरेटिंग सिस्टम प्लेटफ़ॉर्म के लिए विशिष्ट प्रोग्राम) और लिबर में लिखे गए पुस्तकालयों द्वारा कॉल किया जा सकता है अन्य भाषाओं जैसे सी, सी ++ और असेंबली।

http://en.wikipedia.org/wiki/Java_Native_Interface


मजेदार ईस्टर अंडे।
क्रोम के उबंटू संस्करण में, टास्क मैनेजर ( शिफ्ट + एएससी ) में, राइट-क्लिक के साथ आप एक विज्ञान-फाई कॉलम जोड़ सकते हैं जो इतालवी संस्करण में "कैपर टेलीलेटपोर्ट" (टेलीपोर्टेड बकरी) है।

इसके बारे में एक मजाकिया सिद्धांत here





java jni native keyword