2008-10-12 22 views
82

Ryan Delucchi टिप्पणी # 3 में here पूछा 'Tom Hawtin रों जवाब देने के लिए:क्लास.न्यू इंस्टेंस() "बुराई" क्यों है?

क्यों है Class.newInstance() "" बुराई?

इस कोड को नमूना के जवाब में:

// Avoid Class.newInstance, for it is evil. 
Constructor<? extends Runnable> ctor = runClass.getConstructor(); 
Runnable doRun = ctor.newInstance(); 

हां, तो क्यों यह बुराई है?

+9

असल में इस प्रश्न के उत्तर देख रहे हैं: कोई इसे प्रतिबिंब के विभिन्न उपयोगों के बारे में कह सकता है ... न केवल कक्षा। नया इंस्टेंस()। तो यह वास्तव में एक सामान्य अवलोकन है कि "प्रतिबिंब संकलन-समय की जांच को हरा देता है" ... जो अक्सर प्रतिबिंब का बिंदु होता है। –

+23

इन दिनों बच्चे, ओह हाँ वे "EVIL" शब्द के चारों ओर फेंकते हैं लेकिन उन्होंने कभी भी एक कोबोल या फोरट्रान कार्यक्रम नहीं देखा है! आप चाहते हैं कि "ईवीआईएल" 20 साल पुराना फोरट्रान प्रोग्राम देखें, जो परियोजना से परियोजना को टिंकर द्वारा सिमुलेशन पृष्ठभूमि के साथ पास किया गया था और कोई सीएस कभी भी प्रभावित नहीं होता! अब वह "EVIL!" – NoMoreZealots

+0

यह भी देखें http://stackoverflow.com/q/36272566/3888450 –

उत्तर

71

जावा API दस्तावेज़ बताता है कि क्यों (http://java.sun.com/javase/6/docs/api/java/lang/Class.html#newInstance()):

ध्यान दें कि यह विधि किसी भी अपवाद एक जाँच अपवाद सहित nullary निर्माता, द्वारा फेंका प्रसारित। इस विधि का उपयोग प्रभावी रूप से संकलन-समय अपवाद जांच को बाईपास करता है जो अन्यथा संकलक द्वारा किया जाएगा। Constructor.newInstance विधि किसी भी (चेक) InvocationTargetException में कन्स्ट्रक्टर द्वारा फेंक दिया गया कोई अपवाद लपेटकर इस समस्या से बचाता है।

दूसरे शब्दों में, यह चेक अपवाद प्रणाली को हराने में सक्षम हो सकता है।

+11

यह सामान्य रूप से प्रतिबिंब की प्रकृति है ... कन्स्ट्रक्टर के लिए बिल्कुल विशिष्ट नहीं .newInstance()। –

+23

@Ryan: यह सच नहीं है; अन्य सभी प्रतिबिंब-आधारित आमंत्रण विधियां 'InvocationTargetException' नामक एक चेक अपवाद फेंकती हैं जो किसी भी फेंकने योग्य विधि द्वारा फेंकने वाली चीज़ों को लपेटती है। 'Class.newInstance' ऐसा नहीं करेगा --- यह सीधे अपवाद को फेंक देगा। नकारात्मकता यह है कि जावैक आपको उन अपवादों को पकड़ने की कोशिश नहीं करेगा, क्योंकि 'क्लास.न्यू इंस्टेंस' उन्हें फेंकने की घोषणा नहीं की जाती है। –

+1

हू, मैं सही खड़ा हूं :-) धन्यवाद। –

18

एक और कारण:

आधुनिक IDEs आप वर्ग उपयोगों को खोजने के लिए अनुमति देते हैं - यह पुनर्रचना के दौरान मदद करता है अगर आप और आपके आईडीई पता है कि कोड वर्ग है कि आप बदलने की योजना का उपयोग कर रहा है।

जब आप कन्स्ट्रक्टर का स्पष्ट उपयोग नहीं करते हैं, लेकिन इसके बजाय Class.newInstance() का उपयोग करते हैं, तो आप रिफैक्टरिंग के दौरान उस उपयोग को नहीं ढूंढने का जोखिम रखते हैं और जब आप संकलित करते हैं तो यह समस्या स्वयं प्रकट नहीं होगी।

+15

प्रतिबिंब का उपयोग करने का एक सामान्य गोचा भी। –