मैं अज्ञात वर्गों से निपटने का सामना करने वाले एक अजीब व्यवहार को समझना चाहता हूं।जावा: अज्ञात वर्गों की शुरुआत और लागतकर्ता
मैं एक वर्ग है कि इसके निर्माता के अंदर एक संरक्षित प्रणाली को बुलाती है (मुझे पता है, गरीब डिजाइन, लेकिन यह एक और कहानी है ...)
public class A {
public A() {
init();
}
protected void init() {}
}
तो मैं एक और वर्ग है कि A
प्रदान करता है और init()
को ओवरराइड करता है है।
public class B extends A {
int value;
public B(int i) {
value = i;
}
protected void init() {
System.out.println("value="+value);
}
}
अगर मैं कोड
B b = new B(10);
मैं
> value=0
हो और उसकी वजह सुपर वर्ग के निर्माता B
ctor से पहले शुरू हो जाती है और उसके बाद value
अब भी है उम्मीद है।
लेकिन जब इस
class C {
public static void main (String[] args) {
final int avalue = Integer.parsetInt(args[0]);
A a = new A() {
void init() { System.out.println("value="+avalue); }
}
}
}
की तरह एक गुमनाम वर्ग का उपयोग कर रहा value=0
प्राप्त करने के लिए, क्योंकि यह कम या ज्यादा वर्ग B
बराबर होना चाहिए उम्मीद करेंगे: संकलक स्वचालित रूप से एक नया वर्ग C$1
कि A
प्रदान करता है और बनाता है बनाता है उदाहरण चर गुमनाम वर्ग के तरीकों में संदर्भित स्थानीय चर स्टोर करने के लिए, एक बंद आदि का अनुकरण ...
लेकिन जब आप इस चलाने के लिए, मैं
मिला 210> java -cp . C 42
> value=42
प्रारंभ में मैं सोच रहा था कि यह जावा 8 का उपयोग कर रहा था, और शायद, लैमडब्स पेश करते समय, वे हुड के तहत अज्ञात वर्गों को लागू करने के तरीके को बदल दिया (अब आपको final
की आवश्यकता नहीं है) लेकिन मैं जावा 7 भी साथ की कोशिश की और ...
वास्तव में एक ही परिणाम मिला, javap
साथ बाइट कोड को देखते हुए, मैं देख सकता हूँ B
है कि
> javap -c B
Compiled from "B.java"
public class B extends A {
int value;
public B(int);
Code:
0: aload_0
1: invokespecial #1 // Method A."<init>":()V
4: aload_0
5: iload_1
6: putfield #2 // Field value:I
9: return
...
जबकि C$1
के लिए:
> javap -c C\$1
Compiled from "C.java"
final class C$1 extends A {
final int val$v;
C$1(int);
Code:
0: aload_0
1: iload_1
2: putfield #1 // Field val$v:I
5: aload_0
6: invokespecial #2 // Method A."<init>":()V
9: return
....
क्या कोई मुझे बता सकता है कि यह अंतर क्यों? क्या "सामान्य" कक्षाओं का उपयोग करके अज्ञात वर्ग के व्यवहार को दोहराने का कोई तरीका है?
संपादित करें: प्रश्न को स्पष्ट करने के लिए: अनाम वर्गों का प्रारंभिकरण किसी भी अन्य वर्ग (जहां सुपर कन्स्ट्रक्टर किसी अन्य चर को सेट करने से पहले बुलाया जाता है) शुरू करने के नियमों को तोड़ता है? या, क्या सुपर कन्स्ट्रक्टर inovking से पहले B
कक्षा में आवृत्ति चर सेट करने का कोई तरीका है?
आपको क्यों लगता है कि आपका पहला और दूसरा कोड समान है? दूसरे कोड में, आप स्थानीय चर का उपयोग कर रहे हैं। आपके अज्ञात वर्ग विवरण को निष्पादित करने से पहले इसे आरंभ किया जाएगा। –
उम ... ठीक है, आप कहते हैं: तथ्य यह है कि संकलक इस परिदृश्य को लागू करने के लिए एक वर्ग बनाता है डेवलपर को छुपाया जाना चाहिए, इसलिए 'सी $ 1' कक्षा एक विशेष मामला है, और यह ठीक है अगर यह मानक का पालन नहीं करता है कन्स्ट्रक्टर नियम। यह काफी उचित है, लेकिन फिर भी, imho यह थोड़ा अजीब है। – ugo