2015-02-03 2 views
44

से कोटलिन एक्सटेंशन फ़ंक्शंस एक्सेस करना जावा कोड से एक्सटेंशन फ़ंक्शंस तक पहुंच बनाना संभव है?जावा

मैंने कोटलिन फ़ाइल में एक्सटेंशन फ़ंक्शन को परिभाषित किया।

package com.test.extensions 

import com.test.model.MyModel 

/** 
* 
*/ 
public fun MyModel.bar(): Int { 
    return this.name.length() 
} 

जहां MyModel एक (जेनरेट) जावा क्लास है।

MyModel model = new MyModel(); 
model.bar(); 

हालांकि, वह काम नहीं करता: अब, मैं मेरे सामान्य जावा कोड में इसे का उपयोग करना चाहता था। आईडीई bar() विधि को पहचान नहीं पाएगा और संकलन विफल रहता है।

क्या करता है काम kotlin से एक स्थिर समारोह के साथ उपयोग कर रहा है:

public fun bar(): Int { 
    return 2*2 
} 

import com.test.extensions.ExtensionsPackage का उपयोग करके ऐसा मेरी आईडीई ठीक से कॉन्फ़िगर किया जा रहा है।

मैंने कोटलिन दस्तावेज़ों से पूरी जावा-इंटरऑप फ़ाइल की खोज की और बहुत कुछ भी गुगल किया, लेकिन मुझे यह नहीं मिला।

मैं क्या गलत कर रहा हूं? क्या यह भी संभव है?

+0

कृपया * काम नहीं करता * पर विस्तृत करें? क्या यह संकलित करता है, अपवाद फेंकता है, या क्या? क्या आप 'com.est.extensions.MyModel' पैकेज आयात करते हैं? – meskobalazs

+0

@meskobalazs मेरा संपादित उत्तर देखें। – Lovis

+0

@meskobalazs भी, मैं इसे आयात भी नहीं कर सकता। मैं केवल 'com.test.extensions.ExtensionsPackage' आयात कर सकता हूं – Lovis

उत्तर

60

सभी Kotlin कार्यों एक फ़ाइल में घोषित एक ही पैकेज में और एक नाम Kotlin स्रोत फ़ाइल से प्राप्त के साथ एक कक्षा में स्थिर तरीकों को डिफ़ॉल्ट रूप से संकलित किया जाएगा (प्रथम अक्षर को बड़ा और ".kt" विस्तार के साथ बदल दिया "केटी" प्रत्यय)। विस्तार कार्यों के लिए जेनरेट किए गए तरीकों में एक्सटेंशन फ़ंक्शन रिसीवर प्रकार के साथ एक अतिरिक्त पहला पैरामीटर होगा।

इसे मूल प्रश्न पर लागू करने के लिए, जावा कंपाइलर को उदाहरण के साथ कोटलिन स्रोत फ़ाइल दिखाई देगी।kt

package com.test.extensions 

public fun MyModel.bar(): Int { /* actual code */ } 

के रूप में यदि निम्नलिखित जावा वर्ग घोषित किया गया था

package com.test.extensions 

class ExampleKt { 
    public static int bar(MyModel receiver) { /* actual code */ } 
} 

कुछ भी नहीं के रूप में देखने के जावा बिंदु से विस्तारित वर्ग के साथ होता है, तो आप सिर्फ डॉट वाक्य रचना इस तरह के उपयोग करने के लिए उपयोग नहीं कर सकते तरीकों। लेकिन वे अभी भी सामान्य जावा स्थिर तरीके के रूप में प्रतिदेय हैं:

import com.test.extensions.ExampleKt; 

MyModel model = new MyModel(); 
ExampleKt.bar(model); 

स्टेटिक आयात ExampleKt वर्ग के लिए इस्तेमाल किया जा सकता:

import static com.test.extensions.ExampleKt.*; 

MyModel model = new MyModel(); 
bar(model); 
+11

एक्सटेंशन वाले वर्ग के लिए नामकरण सम्मेलन बदल गया है। कृपया वर्तमान होने के लिए उत्तर अपडेट करें। पैकेज 'foo.bar' के भीतर फ़ाइल' Extensions.kt' में एक फ़ंक्शन उदाहरण के साथ 'String.example() 'का संदर्भ' foo.bar.ExtensionsKT.example()' –

+0

से संदर्भित किया जाएगा, इसका मतलब है कि मैं ' जब तक मैं स्थिर कार्य नहीं लिखता तब तक कोटलिन से जावा तक विस्तार का उपयोग नहीं करता? –

+2

जेएफवाईआई, आप कक्षा के नाम को @file: JvmName (" Utils" के साथ भी बदल सकते हैं)। – crgarridos

2

जहां तक ​​मैं यह कह सकता हूं यह संभव नहीं है। एक्सटेंशन किए गए दस्तावेज़ों की मेरी पढ़ने से, ऐसा लगता है कि

public fun MyModel.bar(): Int { 
    return this.name.length() 
} 

हस्ताक्षर

public static int MyModelBar(MyModel obj) { 
    return obj.name.length(); 
} 

तब के साथ एक नई विधि बनाता है, Kotlin रूप myModel.bar(), जहां अगर bar() 'isn की कॉल करने के लिए है कि समारोह के नक्शे MyModel कक्षा में पाया गया यह हस्ताक्षर और नामकरण योजना से मेल खाने वाली स्थिर विधियों की तलाश करता है। ध्यान दें कि यह विस्तारित विधियों को ओवरराइड करने और विस्तारित विधियों को ओवरराइड करने के बारे में उनके बयान से केवल एक धारणा है। मैं निश्चित रूप से जानने के लिए अपने स्रोत में पर्याप्त नहीं मिला है।

तो, मान लीजिए कि उपर्युक्त सत्य है कि कोटलिन एक्सटेंशन को सादे पुराने जावा कोड से बुलाया जाने का कोई तरीका नहीं है, क्योंकि कंपाइलर को किसी ऑब्जेक्ट पर एक अज्ञात विधि दिखाई देगी और त्रुटि हो जाएगी।

+2

यह उत्तर सही नहीं है, उन्हें एक्सेस किया जा सकता है। स्वीकृत उत्तर देखें। –

+0

और संकलक स्थिर तरीकों की तलाश नहीं कर रहा है (विशेष रूप से जावा स्थैतिक तरीकों नहीं)। यह उन एक्सटेंशन विधियों की तलाश में है जिन्हें एक ही फ़ाइल में घोषित या आयात किया गया है। –

7

Kotlin शीर्ष स्तर के विस्तार समारोह जावा स्थिर तरीके के रूप में संकलित किया गया है।

को देखते हुए Kotlin पैकेज foo.bar में दाखिल Extensions.kt युक्त

fun String.bar(): Int { 
    ... 
} 

बराबर जावा कोड होगा:

package foo.bar; 

class ExtensionsKt { 
    public static int bar(String receiver) { 
     ... 
    } 
} 

, जब तक कि है, Extensions.kt लाइन निहित

@file:JvmName("DemoUtils") 

इस मामले में जावा स्थैतिक वर्ग होगा DemoUtils

नामित Kotlin में, विस्तार के तरीकों अन्य तरीकों से घोषित किया जा सकता। (उदाहरण के लिए, सदस्य फ़ंक्शन के रूप में या किसी साथी ऑब्जेक्ट के विस्तार के रूप में।) मैं बाद में इस उत्तर को विस्तारित करने का प्रयास करूंगा।

0

यहाँ अन्य उत्तर एक विस्तार एक Kotlin पैकेज फ़ाइल के शीर्ष स्तर पर स्थित फ़ंक्शन कॉल के मामले को कवर।

हालांकि, मेरे मामले है कि मैं एक एक्सटेंशन एक कक्षा के अंदर स्थित फ़ंक्शन को कॉल करने के लिए आवश्यक था। विशेष रूप से, मैं एक वस्तु से निपट रहा था।

समाधान अविश्वसनीय रूप से सरल है।

तुम सब @JvmStatic अनुसार आपके एक्सटेंशन समारोह व्याख्या है, और देखा क्या करना है! आपका जावा कोड इसका उपयोग करने और इसका उपयोग करने में सक्षम होगा।

1

आप वर्ग फ़ाइलों में अपने कार्यों नकल करने की जरूरत है:

Kotlin फ़ाइल बनाएँ, पूर्व Utils के लिए।kt

कोड दर्ज

class Utils { 
       companion object { 
        @JvmStatic 
        fun String.getLength(): Int {//duplicate of func for java 
         return this.length 
        } 
       } 
      } 

     fun String.getLength(): Int {//kotlin extension function 
      return this.length 
     } 

या

class Utils { 
    companion object { 

     @JvmStatic 
     fun getLength(s: String): Int {//init func for java 
      return s.length 
     } 
    } 
} 

fun String.getLength(): Int {//kotlin extension function 
    return Utils.Companion.getLength(this)//calling java extension function in Companion 
} 

kotlin उपयोग में:

val str = "" 
val lenth = str.getLength() 

जावा में का उपयोग करें:

String str = ""; 
Integer lenth = Utils.getLength(str);