2011-10-02 12 views
5

में अंतिम चर मैं अभी भी बहुत स्काला के लिए नया हूँ, लेकिन मुझे पता है तुम जावास्काला निर्माता

में निम्नलिखित वर्ग चर की तरह

class AClass(aVal: String) 

निर्माता में प्रारंभ कर रहे हैं जो कर रही है जैसा होगा परिभाषित कर सकते हैं

class AClass { 
    private String aVal; 

    public AClass(String aVal) { 
     this.aVal = aVal; 
    } 
} 

जावा में, मैं अंतिम के रूप में एकवल घोषित करता हूं। क्या स्केल सिंटैक्स में एवल वैरिएबल फाइनल बनाने का कोई तरीका है?

संपादित करें:

class AClass(aVal: String) { 
    def printVal() { 
    println(aVal) 
    } 
} 

मैं javap -private भाग गया और जब मैं स्केला वर्ग परिभाषा बदलने के लिए उत्पादन

public class AClass extends java.lang.Object implements scala.ScalaObject{ 
    private final java.lang.String aVal; 
    public void printVal(); 
    public AClass(java.lang.String); 
} 

मिला: यहाँ जब मैं निम्नलिखित स्काला वर्ग संकलन मैं क्या देख रहा हूँ है class AClass(**val** aVal: String) मुझे javap -private

public class AClass extends java.lang.Object implements scala.ScalaObject{ 
    private final java.lang.String aVal; 
    public java.lang.String aVal(); 
    public void printVal(); 
    public AClass(java.lang.String); 
} 
से निम्न आउटपुट मिलता है 210

सार्वजनिक विधि aVal उत्पन्न हुआ है। मैं अभी भी यहां सीख रहा हूं - क्या कोई यह समझा सकता है कि यह क्यों उत्पन्न हुआ है?

नोट मैं स्केला 2,9

उत्तर

10
class AClass(aVal: String) 

उपयोग कर रहा हूँ इस कोड में, Aval एक अंतिम चर रहा है। तो आपके पास पहले से ही एक अंतिम चर है।

class AClass(val aVal: String) 

इस कोड में, एवल अंतिम है और आपके पास एवीएल का गेटटर है। तो अगर आप की तरह नीचे

scala> val a= new AClass("aa") 
a: A1 = [email protected] 

scala> a.aVal 
res2: String = aa 

और अंत में इसका इस्तेमाल कर सकते हैं,

class AClass(var aVal: String) 

इस कोड में, Aval अंतिम नहीं है और आप गेटर और Aval की सेटर की है। तो अगर आप की तरह नीचे

scala> val a= new AClass("aa") 
a: AClass = [email protected] 

scala> a.aVal 
res3: String = aa 

scala> a.aVal = "bb" 
a.aVal: String = bb 

scala> a.aVal 
res4: String = bb 
8

मेरा उत्तर से कॉपी किया गया इसका इस्तेमाल कर सकते हैं: Scala final vs val for concurrency visibility

वहाँ अवधि final के दो अर्थ हैं: क) स्काला क्षेत्रों/तरीकों और जावा तरीकों के लिए इसका मतलब है "में overridded नहीं किया जा सकता एक उपclass "और बी) जावा फ़ील्ड के लिए और जेवीएम बाइटकोड में इसका मतलब है" क्षेत्र को कन्स्ट्रक्टर में प्रारंभ किया जाना चाहिए और फिर से असाइन नहीं किया जा सकता "।

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

यहाँ सबूत है:

scala> class A(val a: Any); class B(final val b: Any); class C(var c: Any) 
defined class A 
defined class B 
defined class C 

scala> import java.lang.reflect._ 
import java.lang.reflect._ 

scala> def isFinal(cls: Class[_], fieldName: String) = { 
    | val f = cls.getDeclaredFields.find(_.getName == fieldName).get 
    | val mods = f.getModifiers 
    | Modifier.isFinal(mods) 
    | } 
isFinal: (cls: Class[_], fieldName: String)Boolean 

scala> isFinal(classOf[A], "a") 
res32: Boolean = true 

scala> isFinal(classOf[B], "b") 
res33: Boolean = true 

scala> isFinal(classOf[C], "c") 
res34: Boolean = false 

या javap, जो आसानी से आरईपीएल से चलाया जा सकता के साथ: एक गैर मामले वर्ग के वर्ग पैरामीटर val के रूप में चिह्नित नहीं है, तो

scala> class A(val a: Any) 
defined class A 

scala> :javap -private A 
Compiled from "<console>" 
public class A extends java.lang.Object implements scala.ScalaObject{ 
    private final java.lang.Object a; 
    public java.lang.Object a(); 
    public A(java.lang.Object); 
} 

या var, और इसे किसी भी तरीके से संदर्भित नहीं किया गया है, इसे केवल कक्षा के निर्माता के लिए दृश्यमान होना चाहिए। स्कैला कंपाइलर तब बाइटकोड से दूर क्षेत्र को अनुकूलित करने के लिए स्वतंत्र है। स्कैला 2.9.1 में, यह काम करता प्रतीत होता है:

scala> class A(a: Any) 
defined class A 

scala> :javap -private A 
Compiled from "<console>" 
public class A extends java.lang.Object implements scala.ScalaObject{ 
    public A(java.lang.Object); 
} 
+0

यूग। मैं पुराने कार्यान्वयन के व्यवहार के साथ अपने निष्कर्षों को पुन: संकलित करना भूल गया था और फिर पुष्टि की थी (http://scala-programming-language.1934581.n4.nabble.com/Val-and-Final-td1993410.html)। आप वास्तव में सही हैं। उप-वर्गों के बारे में मैंने जो समस्या का उल्लेख किया है, वोल्स को ओवरराइड करने में सक्षम है (और यह फाइनल के लिए एक समस्या है) अंतर्निहित क्षेत्र के आधार पर और माता-पिता में जो ओवरराइड किए गए जेनरेटेड कक्षाओं में एक्सेसर्स (जो अंतिम नहीं हैं) के आधार पर घिरा हुआ है। इसे सीधे सेट करने के लिए धन्यवाद। – Chris