2012-06-05 23 views
11

मैं जावा क्लास बनाना चाहता हूं जो स्कैला सेटर्स/गेटर्स सम्मेलन का पालन करता है।जावा क्लास में स्कैला गेटर्स और सेटर्स

मैं साधारण क्लास निम्नलिखित कोशिश की, लेकिन यह काम नहीं करता:

public class JavaA { 
private int a = 0; 

public int a() { 
    return a; 
} 

public void a_$eq(int a) { 
    this.a = a; 
} 
} 

लेकिन जब मैं स्केला से यह तक पहुँचने का प्रयास:

val x = new JavaA 
x.a = 1 

और मैं "रीअसाइनमेंट वैल करने के लिए" त्रुटि संदेश मिलता है । मैंने इसकी तलाश करने की कोशिश की, लेकिन सभी मुद्दों को मैंने पाया जहां स्केल से जावा तक दूसरी तरफ।

ऐसा करने का सही तरीका क्या है?

धन्यवाद!

+0

मैं ईएमएफ (model2model, model2text रूपांतरण) के साथ बहुत कुछ काम कर रहा हूं, इसलिए मैंने सोचा कि मैं कोड को सेटफेट (मूल्य) के बजाय सुविधा = मान के साथ थोड़ा अधिक सुरुचिपूर्ण बना दूंगा। – fikovnik

उत्तर

13

आप केवल ऐसा ही कर सकते हैं, और यह काफी कठिन है कि आप शायद नहीं चाहते हैं।

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

क्या आप करते जावा एक स्काला से परिभाषित इंटरफ़ेस को लागू करने (यानी विशेषता) का उपयोग किया जाता है कर सकते हैं:

// GetSetA.scala 
trait GetSetA { def a: Int; def a_=(a: Int): Unit } 

// JavaUsesGSA.java 
public class JavaUsesGSA implements GetSetA { 
    private int a = 0; 
    public int a() { return a; } 
    public void a_$eq(int a) { this.a = a; } 
} 

क्या आप ऐसा नहीं कर सकते, फिर भी, सीधे क्लास का उपयोग है (फिर क्योंकि जावा स्काला के लिए उपयुक्त एनोटेशन जानकारी) नहीं जोड़ता है:

scala> j.a = 5 
<console>:8: error: reassignment to val 
     j.a = 5 

लेकिन यह बाद से विशेषता सफल लागू करता है ly, आप इसे के रूप में वांछित उपयोग कर सकते हैं जब यह विशेषता के रूप में लिखा गया:

scala> (j: GetSetA).a = 5 
(j: GetSetA).a: Int = 5 

तो यह नहीं बल्कि एक मिश्रित बैग है। किसी भी माध्यम से सही नहीं है, लेकिन कुछ मामलों में मदद करने के लिए यह पर्याप्त रूप से कार्यात्मक हो सकता है।

(अन्य विकल्प, ज़ाहिर है, जावा क्लास से एक अंतर्निहित रूपांतरण प्रदान करना है जिसमें एक गेटर/सेटर है जो जावा क्लास पर वास्तविक तरीकों का संदर्भ देता है; यह तब भी काम करता है जब आपके पास नहीं हो जावा स्काला से विरासत)

(संपादित करें:। बेशक कोई महत्वपूर्ण कारण यह है कि संकलक इस तरह से कार्य करना चाहिए नहीं है, एक बहस कर सकते हैं कि जावा से परिभाषित गेटर/सेटर जोड़े व्याख्या रूप में यदि वे स्काला वाले थे (यानी अगर क्लासफाइल स्पष्ट रूप से स्कैला से नहीं कहता है) जावा इंटरऑपरेबिलिटी में सुधार करने के लिए फीचर एन्हांसमेंट के लिए एक अच्छा उम्मीदवार है।)

+0

अंतर्दृष्टि के लिए धन्यवाद! मुझे चिंता थी कि यह काम नहीं करेगा। – fikovnik

+0

अच्छा; कार्यान्वित विशेषता के साथ शांत चाल! –

1

मुझे डर है कि आप नहीं कर सकते हैं। स्कैला में, एक्सेसर को पैरामीटर सूची के साथ विधि होना चाहिए, जैसे def a = _a। लेखन उदा। स्कैला में def a() = _a एक ही त्रुटि का कारण बनता है, और जावा में कोई पैरामीटर सूची वाले विधि को परिभाषित करने का कोई तरीका नहीं है। आप अपने ScalaSignature उत्पन्न करके स्कैला कंपाइलर को बेवकूफ़ बनाने में सक्षम हो सकते हैं, लेकिन शायद यह समस्या के लायक नहीं है ...

+1

हालांकि समस्या एक्सेसर नहीं है। 'println (x.a) 'ठीक काम करता है (जैसा कि x xa _ = (1)') करता है। –

+1

@TravisBrown यह है, क्योंकि भाषा विनिर्देश के अनुसार, सिंटैक्टिक चीनी केवल तभी काम करती है जब ऐसा कोई एक्सेसर हो। –

+0

आह! आप सही हे। कितना अजीब है। –