2010-06-22 5 views
9

का उपयोग कर मैं एक स्केला पुस्तकालय कक्षा में 2 सरल तरीकों जावा से कहा जा सकता है:कैसे स्केला प्रणाली की घोषणा करने के लिए इतना है कि यह varargs शैली

class Foo { 
    def bar(args : String*) : Unit = println("Foo.bar with: " + args) 
    def bar(args : Array[String]) : Unit = bar(args.toSeq : _*) 
} 

यह सब अच्छी तरह से संकलित करता है। मैं तो एक पुस्तकालय foo.jar में इस डाल दिया और कोशिश करते हैं और जावा के निम्नलिखित टुकड़ा संकलन:

import Foo 
public class Test { 

    public static void main(String[] args) { 
     Foo foo = new Foo(); 
     foo.bar("Hello", "World"); //DOES NOT COMPILE 
    } 
} 

मैं के साथ हमलावर लाइन की जगह ले सकता:

foo.bar(new String[] { "Hello", "World" }); //OK 

लेकिन इस बात को हराने के लिए लगता है। मैं जावा varargs- जैसे वाक्यविन्यास का उपयोग कर जावा से इसे कैसे कॉल कर सकता हूं?

+0

लिखने में कोई त्रुटि है, लेकिन वर्ग हो सकता है '' Foo' foo' विधि नहीं है। –

+0

चीयर्स - टाइपो वास्तव में –

+0

मैंने जो कहा है उसमें मैं स्पष्ट रूप से गलत हूं, हालांकि मैं स्वीकार करता हूं कि यह मुझे भ्रमित करता है। मैं गलत जानकारी फैलाने से बचने के लिए अपना जवाब हटा रहा हूं। –

उत्तर

3

2.8 में (लगभग 2.7 पता नहीं), यदि आप एक जावा इंटरफ़ेस से एक जावा माता पिता से एक varargs विधि ओवरराइड भी कार्यान्वित एक varargs विधि, तो स्काला संकलक दो तरीकों उत्पन्न होगा , स्कैला के लिए एक, जावा के लिए एक। जावा एक - जैसा कि आप बाइटकोड का निरीक्षण करके स्वयं के लिए देख सकते हैं - बस varargs सरणी लेता है और इसे लपेटता है, फिर रैप संस्करण में WrappedArray को पारित करता है जो एक सेक की अपेक्षा कर रहा है।

यदि कंपेलर को अन्य परिस्थितियों में आगे बढ़ाने के लिए मजबूर करने का कोई तरीका है, तो मुझे इसके बारे में पता नहीं है। मुझे संदेह है कि यह अस्तित्व में है। ऐसा लगता है कि इसके लिए पूछने का एक तरीका प्रदान करना (एक एनोटेशन, मुझे लगता है) एक उचित वृद्धि अनुरोध होगा।

1

बिल्कुल निश्चित नहीं है लेकिन मुझे लगता है कि स्कैला में विविधता अनुक्रमों का उपयोग करती है और जावा कार्यान्वयन से अलग होती है। मुझे लगता है कि सबसे आसान तरीका है पूरा करने के लिए आप क्या चाहते हैं जावा में फू स्केला वर्ग उपवर्ग और एक बार विधि है कि एक जावा लेता जोड़ना है vararg यानी

public class JavaFoo extends Foo { 
    public void bar(String... args) { 
     super.bar(args) 
    } 
} 

JavaFoo vararg विधि तो जावा में vararg सिंटैक्स का उपयोग कहा जा सकता है ।

आशा है कि यह मदद करता है :)

+1

हमम ... डैनियल के सुझाव की कोशिश की, लेकिन मैं इसे स्कैला 2.8 बीटा का उपयोग करके काम नहीं कर सका। क्या जावा वर्गार्ग और स्केल वैरर्ग दोनों को संकलन कुछ हाल ही में जोड़ा गया है? बाइटकोड को कम करने से सार्वजनिक सार्वजनिक बार (सीक तर्क) विधि के साथ एक फू क्लास उत्पन्न होता है ... –

0

स्केल कंपाइलर को "संगत" होने के लिए मजबूर करने के लिए जावा इंटरफ़ेस का उपयोग करने के बारे में उपयोगी संकेत के बावजूद, मैं बस अपना कोड काम करने के लिए नहीं मिला। आखिरकार यह मेरे सामने आया कि विधियों को स्कैला ऑब्जेक्ट पर घोषित किया गया था, जिसका अर्थ है कि वे वास्तव में स्थैतिक हैं, और आप इंटरफ़ेस में स्थिर विधियां निर्दिष्ट नहीं कर सकते हैं, इसलिए संकलक मूल रूप से इस तथ्य को अनदेखा कर रहा था कि ऑब्जेक्ट ने इंटरफ़ेस को कार्यान्वित किया । सौभाग्य से मेरे लिए, एक काम है। इसके बजाय जावा से सीधे इस तरह स्थिर विधि बुलाने की:

CLASS.method(x,y,z) 

आप इसे इस तरह कॉल करनी होगी:

CLASS$.MODULE$.method(x,y,z) 

इसका मतलब है आप तथ्य यह है एक उदाहरण के रूप में संदर्भित सिंगलटन वस्तु तक पहुँचने में हैं एक स्थैतिक क्षेत्र द्वारा, और चूंकि यह एक उदाहरण है, और जावा इंटरफ़ेस लागू करता है, वहां संकलक यह ठीक से काम करता है और varargs विधि लागू करता है ताकि जावा इसे एक varargs के रूप में कॉल कर सके।

मुझे व्यक्तिगत रूप से लगता है कि इसे स्कैला कंपाइलर बग के रूप में माना जाना चाहिए।

1

answer to this question देखें:

आप @annotation.varargs उपयोग कर सकते हैं स्केला का निर्देश देने की दोनों तरीकों उत्पन्न करने के लिए:

class Foo { 
    @annotation.varargs def bar(args : String*) : Unit = println("Foo.bar with: " + args) 
    def bar(args : Array[String]) : Unit = bar(args.toSeq : _*) 
} 
संबंधित मुद्दे