2010-07-19 19 views
21

मैं अपने मौजूदा जावा ऐप में कुछ स्कैला कोड इंजेक्ट करने की कोशिश कर रहा हूं। (इसलिए, कहा जा रहा है, मैं कुछ और मजेदार चाहता हूँ)।आप जावा से स्कैला सिंगलटन विधि कैसे कॉल करते हैं?

मैं अब स्काला

ScalaPower.scala 

    package org.fun 
    class ScalaPower 
    object ScalaPower{ 
     def showMyPower(time:Int) = { 
     (0 to time-1).mkString(", ") 
     } 
    } 

में एक सिंगलटन सामान बनाते हैं, OldJava.java

class OldJava { 
    public void demo(){ 
    System.out.println(?) 
    } 
} 

अंदर मैं ? ताकि जावा showMyPower विधि कॉल करेंगे क्या भरना चाहिए? मैंने org.fun.ScalaPower.showMyPower(10) और org.fun.ScalaPower.getInstance().showMyPower(10) दोनों को आजमाया लेकिन कोई भी काम नहीं किया।

(JAD का उपयोग कर वर्ग फ़ाइल डिकंपाइल मुझे लेकिन बकवास कोड कुछ भी नहीं दिखा।)

संपादित मैं class ScalaPower घोषणा को हटा दें और अपेक्षा के अनुरूप स्केला स्थिर विधि का उत्पादन। (org.fun.ScalaPower.showMyPower(10) पर कॉल करें बस काम करता है)।

आश्चर्य अगर यह स्केला संकलक में एक बग या नहीं मन में

+1

के बारे में क्या 'org.fun.ScalaPower.showMyPower (10)'? – OscarRyz

+0

ओच, मेरे बुरे। नामस्थान बदलने के लिए भूल गए। पहले ही सवाल अपडेट किया गया है। धन्यवाद। –

+1

वैसे, आप '0 से समय-1' के बजाय '0 तक समय' लिख सकते हैं। –

उत्तर

9

मुझे लगता है कि यह परोक्ष रूप से यह शामिल हैं:

साथी ऑब्जेक्ट्स और जावा स्टेटिक तरीके

के बारे में साथी वस्तुओं पता करने के लिए एक और बात है। जब भी आप को किसी अनुप्रयोग के लिए प्रविष्टि बिंदु के रूप में उपयोग करने के लिए एक मुख्य विधि परिभाषित करते हैं, तो स्कैला आपको इसे किसी ऑब्जेक्ट में रखने की आवश्यकता है। हालांकि, इस लेखन के समय मुख्य विधियों को साथी ऑब्जेक्ट में परिभाषित नहीं किया जा सकता है। जेनरेट कोड में कार्यान्वयन विवरण के कारण, JVM को मुख्य विधि नहीं मिलेगी। भविष्य में रिलीज में यह समस्या हल हो सकती है। अभी के लिए, आपको किसी भी मुख्य विधि को सिंगलटन ऑब्जेक्ट (यानी, "गैर-साथी" ऑब्जेक्ट) [स्कैलाटिप्स] में परिभाषित करना होगा। सरल व्यक्ति वर्ग और साथी ऑब्जेक्ट का मुख्य उदाहरण देखें जो मुख्य परिभाषित करने का प्रयास करता है।

यहां पाया के रूप में: http://programming-scala.labs.oreilly.com/ch06.html

संक्षेप में, क्योंकि आपके वस्तु एक साथी वस्तु (एक साथी वर्ग है) आप इसे नहीं कर सकता की तरह आप उम्मीद है। जैसा कि आपने पाया कि क्या आप कक्षा से छुटकारा पा सकते हैं, यह काम करेगा।

+2

यह अब सच नहीं है। जब लिखा गया था और स्कैला 2 के बीच कहीं कहीं।8 जारी किया गया था, अग्रेषण कोड जनरेशन पैटर्न को साथी में मुख्य तरीकों की अनुमति देने के लिए तय किया गया था। –

+0

ओह, उत्कृष्ट। पुस्तक ने संकेत दिया कि वे चाहते हैं कि यह बदलेगा, लेकिन 2.8 के लिए नहीं कहा (और उनके पास 2.8-नेस की बहुत उम्मीद थी)। यह कहा गया कि मूल प्रश्नकर्ता अपना संस्करण नहीं देता है, और "संपादित करें मैं वर्ग स्कैलापावर घोषणा को हटाता हूं और स्कैला स्थिर विधि को अपेक्षित रूप से उत्पन्न करता है।" यह अभी भी लगता है कि समस्या हो सकती है। –

+0

धन्यवाद। यह मेरी स्थिति की व्याख्या करता है। मैं अभी स्केल 2.8 पर स्विच कर रहा हूं। नरक, ग्रहण स्कैला प्लगइन अभी भी बेकार है। –

3

रखें कि शेयर javap उपकरण को देखने के लिए क्या स्काला संकलक का उत्पादन किया जा सकता है है। यह निश्चित रूप से आपके प्रश्न का उत्तर नहीं देता है, लेकिन जब आपको आवश्यकता होती है तो कोड जनरेशन पैटर्न को याद दिलाना है, यह पर्याप्त है।

+0

धन्यवाद। जब मैं घर वापस आऊंगा तो मैं कोशिश करूंगा। (अब काम पर) –

10

आपको क्या त्रुटियां मिल रही थीं? अपने स्काला नमूना का उपयोग करता है और निम्नलिखित जावा वर्ग:

cat test.java:


import org.fun.*; 

public class test { 
    public static void main(String args[]) { 
     System.out.println("show my power: " + ScalaPower.showMyPower(3));  
    } 
} 

और यह चल रहा है इस प्रकार है:

show my power: 0, 1, 2

:

java -cp .:<path-to/scala/install-dir>/lib/scala-library.jar test

मेरी उत्पादन देता है

+1

हम्म, यह अजीब है। मेरा कोड संकलित भी नहीं करता है। यह कह रहा है कि 'प्रतीक' शो माईपावर 'नहीं मिला "(हालांकि आईडीईए स्कैला प्लगइन इसे समझता है, और मुझे एक ऑटो-पूर्णता प्रदान करता है) –

+0

मुझे लगता है कि वास्तव में विधि' शो माईपावर 'को स्कैला $ के अंदर घोषित किया गया है, स्कैला नहीं। स्कैला का कौन सा संस्करण आप उपयोग कर रहे हैं जो इन कोड को संकलित करने योग्य बनाता है? मैं 2.7.5 –

+0

ओच, 'org.fun.ScalaPower $ का उपयोग कर रहा हूं। $ $ .ShowMyPower' वास्तव में सही तरीका है जिसे मुझे कॉल करना चाहिए, क्या बिल्ली है? –

1

अपेक्षा के अनुरूप

class ScalaPower 
object ScalaPower{ 
    def showMyPower(time:Int) = { 
    (0 to time-1).mkString(", ") 
    } 
} 

ScalaPower.showMyPower(10) काम करता करने के बाद।

14

आमतौर पर सिंगलटन को अपनी कक्षा से एक्सेस करना बेहतर होता है।

इस मामले में:

org.fun.ScalaPower$.MODULE$.showMyPower(10); 

कार्यान्वयन विवरण में बहुत ज्यादा जा रहा बिना, स्काला वस्तु और कक्षा/विशेषता के बीच नामस्थान अलग करती है। इसका मतलब है कि वे एक ही नाम का उपयोग कर सकते हैं। हालांकि, किसी ऑब्जेक्ट में एक वर्ग होता है, और इसलिए JVM पर एक उलझन वाले नाम की आवश्यकता होती है। वर्तमान स्काला सम्मेलन मॉड्यूल नाम (शीर्ष-स्तरीय मॉड्यूल के लिए) के अंत में एक $ जोड़ना है। यदि वस्तु को कक्षा में परिभाषित किया गया है, तो मेरा मानना ​​है कि सम्मेलन OuterClass $ मॉड्यूलनाम $ है। ScalaPower मॉड्यूल की सिंगलटन प्रॉपर्टी को लागू करने के लिए, मॉड्यूलनाम $ वर्ग का एक स्थिर मॉड्यूल $ सदस्य भी है। यह कक्षा लोड समय पर शुरू किया गया है, यह सुनिश्चित करना कि केवल एक उदाहरण है। इसका एक दुष्प्रभाव यह है कि आपको मॉड्यूल के कन्स्ट्रक्टर में लॉकिंग का कोई भी प्रकार नहीं करना चाहिए।

किसी भी मामले में, स्कैला ने इसे "जावा के लिए चीजों को अच्छे बनाने" स्थिर-फॉरवर्डर्स तंत्र में भी बनाया है। यह वह जगह है जहां यह स्कैलापावर क्लास पर स्थिर विधियां लिखती है जो केवल स्कैलापावर $ को कॉल करती हैं। $ .OomeMethod()। यदि आप एक साथी वर्ग को भी परिभाषित करते हैं, तो जेनरेट किए जा सकने वाले फॉरवर्डर्स सीमित हैं, क्योंकि आपको JVM पर स्थिर और इंस्टेंस-स्तरीय विधियों के साथ संघर्ष नाम देने की अनुमति नहीं है। मुझे लगता है कि 2.8.0 में इसका मतलब है कि यदि आपके पास साथी वस्तु है, तो आप अपने स्थिर फॉरवर्डर्स को खो देते हैं।

इस मामले में हमेशा "सर्वोत्तम अभ्यास" हमेशा स्केलपावर $ का उपयोग करना होगा। एक स्थिर फॉरवर्डर के बजाय $ संदर्भ का संदर्भ लें, क्योंकि फॉरवर्डर स्कालापावर क्लास में संशोधन के साथ गायब हो सकता है।

संपादित करें: टाइपो

+0

यहां कोड में मॉड्यूल $ में एक टाइपो है –

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