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


476

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

जावा में मूल कीवर्ड किसके लिए उपयोग किया जाता है?


जवाबों:


343

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


3
वास्तविक कार्यान्वयन में जेएनआई का उपयोग नहीं करना है। JRE द्वारा कुछ JRE विधियों को आंतरिक रूप से नियंत्रित किया जाता है। वास्तव में, यह भी अनिवार्य नहीं है कि कार्यान्वयन वास्तव में मूल कोड है। यह सिर्फ "जावा प्रोग्रामिंग भाषा के अलावा अन्य भाषा में लागू किया गया है"
होल्गर

443

न्यूनतम रननीय उदाहरण

Main.java

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));
    }
}

main.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

Ubuntu 14.04 AMD64 पर परीक्षण किया गया। Oracle JDK 1.8.0_45 के साथ भी काम किया।

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

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

व्याख्या

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

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

यह करने के लिए इस्तेमाल किया जा सकता है:

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

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

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

Android NDK

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

आधिकारिक NDK रिपॉजिटरी में हैलो-जानी ऐप जैसे "कैनोनिकल" उदाहरण शामिल हैं:

आप में unzipएक .apkNDK एंड्रॉयड हे पर के साथ, आप पहले से संकलित देख सकते हैं .soके तहत मूल कोड से मेल खाती है कि lib/arm64-v8a/libnative-lib.so

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

OpenJDK 8 में उदाहरण

आइए पाते हैं कि Object#clonejdk8u60-b27 में कहां परिभाषित किया गया है।

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

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

find . -name Object.java

जो हमें jdk / src / share / classes / java / lang / object.java # l212 पर ले जाता है :

protected native Object clone() throws CloneNotSupportedException;

अब कठिन हिस्सा आता है, जहां यह पता चलता है कि क्लोन सभी अप्रत्यक्ष के बीच है। क्वेरी से मुझे मदद मिली:

find . -iname object.c

जो या तो C या 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

जो हमें हॉटस्पॉट / src / share / vm / prims / jvm.cpp # l580 की ओर ले जाता है :

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

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


1
बहुत बढ़िया जवाब। बस एक फुटनोट: एक static nativeजावा विधि के लिए, C ++ फ़ंक्शन का दूसरा पैरामीटर टाइप jclassऔर नहीं है jobject
SR_

@SR_ जानकारी के लिए धन्यवाद। क्या मेरे उत्तर में कोई गलती थी, या यह केवल कुछ अतिरिक्त जानकारी है?
सिरो सेंटिल्ली 郝海东 冠状 iro i 法轮功 '

2
@ यह उन लोगों के लिए कुछ अतिरिक्त जानकारी है, जो आपके उदाहरण से शुरू होते हैं (एसओ पर लगभग 300 के साथ एक उत्तर संदर्भ के रूप में काम कर सकता है)। मेरे पास एक गलत हस्ताक्षर के साथ एक फ़ंक्शन है, जिसे स्टैक पर एक गड़बड़ी के साथ बुलाया गया है, जिसमें कोई त्रुटि रिपोर्ट नहीं की गई है (किसी भी संकलन, लिंक या रन समय पर)। इस प्रकार मुझे इस कदम पर सावधान रहना महत्वपूर्ण है।
SR_

419

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

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

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

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

इसके अलावा जावा नेटिव इंटरफेस स्पेसिफिकेशन देखें


3
यह मेरी समझ है मैं जावा फ़ाइल में System.currentTimeMillis () (जो कि मूल है) लिखता हूं और फिर यह काम करने के लिए, JNI पुस्तकालयों या C या C ++ या असेंबली भाषा में लिखे गए कुछ फ़ंक्शन को कॉल करेगा और फिर कुछ मूल्य वापस मेरे जावा कोड पर लौटाएगा । पूर्व: यहाँ currentTimeMillis विधि JNI की मदद से एक मूल कोड को आमंत्रित करती है और उस मूल कोड सिस्टम संसाधन से बात करती है ex: मदरबोर्ड पर बैठा एक टाइमर और इस प्रकार रिटर्न वैल्यू (सिस्टम समय) प्राप्त करता है। कृपया मुझे सुधारो, कृपया
एमकेओडी

4
@MKod विधियाँ currentTimeMillisJDK का हिस्सा हैं और इन्हें एनोटेट किया जाता है nativeक्योंकि कार्यान्वयन JDK स्रोत कोड में ही होता है। यह बहुत संभावना नहीं है कि कार्यान्वयन विधानसभा भाषा का उपयोग करता है; यह शायद ऑपरेटिंग सिस्टम का एक एपीआई तरीका कहता है जो JVM शीर्ष पर चल रहा है। उदाहरण के लिए विंडोज पर यह GetSystemTimeकर्नेल 32.dll में DLL विधि कह सकता है । दूसरे OS पर इसका अलग कार्यान्वयन होगा। हालाँकि जब आप nativeएक विधि के लिए उपयोग करते हैं जो आप लिख रहे हैं (एक JDK विधि के विपरीत) तो आपको JNI का उपयोग करके कार्यान्वयन प्रदान करना होगा।
एडम बर्ले

यह कथन मूल-निवासी कीवर्ड के लिए महत्वपूर्ण है ... 'आपको सिस्टम या हार्डवेयर संसाधनों तक पहुंचने की आवश्यकता है जो केवल दूसरी भाषा (आमतौर पर C) से उपलब्ध हैं।'
atkqkhaled

@ किडर्बला मैं पूछ सकता हूं कि "जेडीके स्रोत कोड में ही कार्यान्वयन" से आपका क्या मतलब है? currentTimeMillisमूल के रूप में चिह्नित है, java.lang.Systemइसलिए यह जेएनआई का उपयोग करता है, क्या यह सही नहीं है?
flow2k

1
@ flow2k हाँ, आपने जो कहा है वह शायद सच है, मुझे यकीन नहीं है कि मैंने अपनी टिप्पणी में (2 साल से अधिक समय पहले) क्यों कहा
एडम बुर्ले

59

से सीधे जावा भाषा विशिष्टता :

एक विधि जिसे nativeप्लेटफ़ॉर्म-डिपेंडेंट कोड में लागू किया जाता है, आमतौर पर C, C ++, FORTRAN, या असेंबली भाषा जैसी किसी अन्य प्रोग्रामिंग भाषा में लिखी जाती है। एक nativeविधि का शरीर केवल एक अर्धविराम के रूप में दिया जाता है, यह दर्शाता है कि कार्यान्वयन एक ब्लॉक के बजाय, छोड़ा गया है।


19

जैसा कि SLaks ने उत्तर दिया, nativeकीवर्ड मूल कोड को कॉल करने के लिए है।

इसका उपयोग GWT द्वारा जावास्क्रिप्ट विधियों को लागू करने के लिए भी किया जाता है ।


13

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

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

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


8

NATIVE नॉन एक्सेस मोडिफायर है। इसे केवल METHOD पर लागू किया जा सकता है। यह विधि या कोड के PLATFORM-DEPENDENT कार्यान्वयन को इंगित करता है।


6

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


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

3

जावा nativeविधि जावा कोड के लिए ओएस देशी कोड को कॉल करने के लिए एक तंत्र प्रदान करती है, या तो कार्यात्मक या प्रदर्शन कारणों के कारण।

उदाहरण:

606  public native int availableProcessors();
617  public native long freeMemory();
630  public native long totalMemory();
641  public native long maxMemory();
664  public native void gc();

Runtime.classOpenJDK में संबंधित फ़ाइल में, JAVA_HOME/jmods/java.base.jmod/classes/java/lang/Runtime.classइन विधियों को समाहित करता है और उन्हें ACC_NATIVE( 0x0100) के साथ टैग किया जाता है , और इन विधियों में कोड विशेषता नहीं होती है , जिसका अर्थ है कि इन विधि में Runtime.classफ़ाइल में कोई वास्तविक कोडिंग तर्क नहीं है :

  • विधि 13 availableProcessors: मूल और कोई कोड विशेषता के रूप में टैग की गई
  • विधि 14 freeMemory: मूल और कोई कोड विशेषता के रूप में टैग की गई
  • विधि 15 totalMemory: मूल और कोई कोड विशेषता के रूप में टैग की गई
  • विधि 16 maxMemory: मूल और कोई कोड विशेषता के रूप में टैग की गई
  • विधि 17 gc: मूल और कोई कोड विशेषता के रूप में टैग की गई

यहाँ छवि विवरण दर्ज करें

वास्तव में कोडिंग तर्क संगत Runtime.c फ़ाइल में है:

42  #include "java_lang_Runtime.h"
43
44  JNIEXPORT jlong JNICALL
45  Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
46  {
47      return JVM_FreeMemory();
48  }
49
50  JNIEXPORT jlong JNICALL
51  Java_java_lang_Runtime_totalMemory(JNIEnv *env, jobject this)
52  {
53      return JVM_TotalMemory();
54  }
55
56  JNIEXPORT jlong JNICALL
57  Java_java_lang_Runtime_maxMemory(JNIEnv *env, jobject this)
58  {
59      return JVM_MaxMemory();
60  }
61
62  JNIEXPORT void JNICALL
63  Java_java_lang_Runtime_gc(JNIEnv *env, jobject this)
64  {
65      JVM_GC();
66  }
67  
68  JNIEXPORT jint JNICALL
69  Java_java_lang_Runtime_availableProcessors(JNIEnv *env, jobject this)
70  {
71      return JVM_ActiveProcessorCount();
72  }

और इन Cकोडिंग को libjava.so(लिनक्स) या libjava.dll(विंडोज) फ़ाइल में संकलित किया गया है JAVA_HOME/jmods/java.base.jmod/lib/libjava.so:

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

संदर्भ

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.