में स्विंग के ऐड() जैसे अतिव्यापी तरीकों को कॉल करना मुझे पता है कि कन्स्ट्रक्टरों से ओवरराइड करने योग्य तरीकों को कॉल करना एक बुरा विचार है। लेकिन मैं यह भी देखता हूं कि यह स्विंग के साथ हर जगह किया जा रहा है, जहां add(new JLabel("Something"));
जैसे कोड हर समय रचनाकारों में होते हैं।कन्स्ट्रक्टर
उदाहरण के लिए नेटबीन आईडीई लें। यह रचनाकारों में अतिसंवेदनशील कॉल के बारे में बहुत पसंद है। और फिर भी, जब यह स्विंग कोड उत्पन्न करता है, तो यह उन add()
विधि को initializeComponents()
विधि में कॉल करता है ... जिसे तब निर्माता से कहा जाता है! किसी समस्या को छिपाने और चेतावनी को अक्षम करने का एक अच्छा तरीका (नेटबीन में "एक निजी विधि नहीं है जो ओवरराइड करने योग्य विधियों को कन्स्ट्रक्टर" चेतावनी से बुलाया जाता है)। लेकिन वास्तव में समस्या को हल करने का कोई तरीका नहीं है।
यहां क्या हो रहा है? मैं इसे उम्र के लिए कर रहा हूं, लेकिन हमेशा इसके बारे में एक असहज महसूस कर रहा था। अतिरिक्त init()
विधि (और इसे हर बार कॉल करने के लिए भूलना नहीं भूल रहा है, जो कि उबाऊ है) को छोड़कर स्विंग कंटेनर को शुरू करने का एक बेहतर तरीका है?
public class MyBasePanel extends JPanel {
public MyBasePanel() {
initializeComponents();
}
private void initializeComponents() {
// layout setup omitted
// overridable call
add(new JLabel("My label"), BorderLayout.CENTER);
}
}
public class MyDerivedPanel extends MyBasePanel {
private final List<JLabel> addedLabels = new ArrayList<>();
@Override
public void add(Component comp, Object constraints) {
super.add(comp);
if (comp instanceof JLabel) {
JLabel label = (JLabel) comp;
addedLabels.add(label); // NPE here
}
}
}
यह कोड क्लीनर रख सकता है, लेकिन यह इसे * सुरक्षित * नहीं बनाता है। इसके विपरीत, समस्या अब छिपी हुई है, लेकिन यह अभी भी वहां है। हालांकि init फ़ंक्शन निजी है, फिर भी यह 'कॉल() 'जैसे कार्यों को कॉल करता है, नहीं हैं। तो अगर कोई 'add() 'ओवरराइड करता है, तो आपको बिल्कुल वही समस्या होगी, केवल एक निजी फ़ंक्शन में छिपी हुई है! यह मेरे प्रश्न का मुद्दा है। –
उदाहरण के लिए मेरा संपादन देखें। –