java सिंटैक्स खराब अभ्यास को पूरा करने के लिए सिर्फ एक वापसी बयान है?




return try-catch (11)

क्या सिंटैक्स को संतुष्ट करने और संकलन त्रुटियों से बचने के लिए अंत में अतिरिक्त रिटर्न स्टेटमेंट डालना बुरा व्यवहार है (एक टिप्पणी के साथ यह समझा नहीं जाएगा)

मुझे लगता है कि return null एक पहुंच योग्य शाखा के टर्मिनस के लिए खराब अभ्यास है। RuntimeException को फेंकना बेहतर है ( AssertionError भी स्वीकार्य होगा) क्योंकि उस पंक्ति को पाने के लिए कुछ गलत हो गया है और एप्लिकेशन अज्ञात स्थिति में है। इस तरह की अधिकांश (ऊपर की तरह) है क्योंकि डेवलपर ने कुछ याद किया है (ऑब्जेक्ट्स कोई भी शून्य और अन-क्लोनबल नहीं हो सकता है)।

मैं संभवतः InternalError उपयोग नहीं करता जब तक कि मुझे बहुत यकीन नहीं है कि कोड पहुंच योग्य नहीं है (उदाहरण के लिए System.exit() बाद) क्योंकि यह अधिक संभावना है कि मैं वीएम की तुलना में गलती करता हूं।

मैं केवल एक कस्टम अपवाद (जैसे TotallyFooException ) का उपयोग करता TotallyFooException अगर उस "पहुंचने योग्य रेखा" पर पहुंचने का अर्थ उस अपवाद के समान होता है जहां आप उस अपवाद को फेंक देते हैं।

निम्नलिखित कोड पर विचार करें:

public Object getClone(Cloneable a) throws NullPointerException {

    if (a != null) {
        throw new TotallyFooException();
    }
    else {
        try {
            return a.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

return null; एक अपवाद पकड़ा जा सकता है क्योंकि एक अपवाद पकड़ा जा सकता है, हालांकि इस तरह के मामले में हम पहले से ही जांच चुके हैं कि यह शून्य था (और मान लें कि हम उस कक्षा को जानते हैं जिसे हम बुला रहे हैं क्लोनिंग का समर्थन करते हैं) ताकि हम जान सकें कि कोशिश कथन कभी विफल नहीं होगा।

क्या सिंटैक्स को संतुष्ट करने और संकलन त्रुटियों से बचने के लिए अंत में अतिरिक्त रिटर्न स्टेटमेंट डालना बुरा व्यवहार है (एक टिप्पणी के साथ यह समझाया नहीं जाएगा), या इस तरह कुछ कोड करने का एक बेहतर तरीका है ताकि अतिरिक्त वापसी कथन अनावश्यक है?


वापसी शून्य; एक अपवाद पकड़ा जा सकता है क्योंकि एक अपवाद पकड़ा जा सकता है, हालांकि इस तरह के मामले में हम पहले से ही जांच चुके हैं कि यह शून्य था (और मान लें कि हम उस कक्षा को जानते हैं जिसे हम बुला रहे हैं क्लोनिंग का समर्थन करते हैं) ताकि हम जान सकें कि कोशिश कथन कभी विफल नहीं होगा।

यदि आपको ऐसे तरीके से शामिल इनपुट के बारे में जानकारी पता है जहां आप जानते हैं कि try कथन कभी विफल नहीं हो सकता है, तो इसका क्या मतलब है? try बचें यदि आप निश्चित रूप से जानते हैं कि चीजें हमेशा सफल होने जा रही हैं (हालांकि यह दुर्लभ है कि आप अपने कोडबेस के पूरे जीवनकाल के लिए पूरी तरह से सुनिश्चित हो सकते हैं)।

किसी भी मामले में, संकलक दुर्भाग्य से एक दिमाग पाठक नहीं है। यह फ़ंक्शन और इसके इनपुट को देखता है, और इसके पास दी गई जानकारी को देखते हुए, इसे आपके पास नीचे दिए गए return स्टेटमेंट की आवश्यकता होती है।

क्या सिंटैक्स को संतुष्ट करने और संकलन त्रुटियों से बचने के लिए अंत में अतिरिक्त रिटर्न स्टेटमेंट डालना बुरा व्यवहार है (एक टिप्पणी के साथ यह समझाया नहीं जाएगा), या इस तरह कुछ कोड करने का एक बेहतर तरीका है ताकि अतिरिक्त वापसी कथन अनावश्यक है?

काफी विपरीत, मैं सुझाव दूंगा कि किसी भी कंपाइलर चेतावनियों से बचने के लिए यह अच्छा अभ्यास है, उदाहरण के लिए, भले ही वह कोड की एक और पंक्ति खर्च करे। यहां लाइन गिनती के बारे में ज्यादा चिंता न करें। परीक्षण के माध्यम से समारोह की विश्वसनीयता स्थापित करें और फिर आगे बढ़ें। सिर्फ यह बताते हुए कि आप return स्टेटमेंट को छोड़ सकते हैं, कल्पना करें कि एक साल बाद उस कोड पर वापस आना और फिर यह तय करने का प्रयास करें कि नीचे दिया गया return स्टेटमेंट कुछ टिप्पणी के मुकाबले ज्यादा भ्रम पैदा कर रहा है, इस बात की वजह से कि यह अनुमानों के कारण क्यों छोड़ा गया था आप इनपुट पैरामीटर के बारे में कर सकते हैं। सबसे अधिक संभावना है कि return स्टेटमेंट से निपटना आसान हो जाएगा।

उस ने कहा, विशेष रूप से इस हिस्से के बारे में:

try {
    return a.clone();
} catch (CloneNotSupportedException e) {
   e.printStackTrace();
}
...
//cant be reached, in for syntax
return null;

मुझे लगता है कि यहां अपवाद-हैंडलिंग मानसिकता के साथ थोड़ा सा अजीब बात है। आप आमतौर पर ऐसी साइट पर अपवादों को निगलना चाहते हैं जहां आपके पास कुछ अर्थपूर्ण है जो आप प्रतिक्रिया में कर सकते हैं।

आप एक लेनदेन तंत्र के रूप में try/catch बारे में सोच सकते हैं। इन परिवर्तनों को try करें, अगर वे विफल हो जाते हैं और हम catch ब्लॉक में शाखा बनाते हैं, तो रोलबैक और पुनर्प्राप्ति प्रक्रिया के हिस्से के रूप में प्रतिक्रिया में (जो भी catch ब्लॉक में है) करें।

इस मामले में, केवल एक स्टैकट्र्रेस प्रिंट करना और फिर शून्य को वापस करने के लिए मजबूर होना एक लेनदेन / वसूली मानसिकता नहीं है। कोड विफलता के लिए मैन्युअल रूप से जांचने के लिए सभी कोड कॉलिंग getClone करने के लिए त्रुटि-हैंडलिंग ज़िम्मेदारी स्थानांतरित करता है। आप CloneNotSupportedException को पकड़ना पसंद कर सकते हैं और इसे दूसरे, अपवाद के अधिक अर्थपूर्ण रूप में अनुवादित कर सकते हैं और उसे फेंक सकते हैं, लेकिन आप अपवाद को निगलना नहीं चाहते हैं और इस मामले में एक शून्य वापस नहीं करना चाहते क्योंकि यह लेनदेन-वसूली साइट की तरह नहीं है ।

अपवाद फेंकने पर, आप विफलताओं को मैन्युअल रूप से जांचने और निपटने के लिए कॉलर्स को जिम्मेदारियों को लीक कर देंगे।

ऐसा लगता है कि आप एक फ़ाइल लोड करते हैं, यह उच्च स्तरीय लेनदेन है। आपके पास वहां try/catch हो सकती है। फ़ाइल लोड करने की trying करने की प्रक्रिया के दौरान, आप ऑब्जेक्ट क्लोन कर सकते हैं। यदि इस उच्च स्तरीय ऑपरेशन (फ़ाइल लोड करना) में कहीं भी विफलता है, तो आप आम तौर पर इस शीर्ष-स्तरीय लेन-देन try/catch ब्लॉक पर अपवाद फेंकना चाहते हैं ताकि आप फ़ाइल लोड करने में विफलता से कृपापूर्वक पुनर्प्राप्त कर सकें (चाहे यह क्लोनिंग या किसी और चीज में त्रुटि के कारण है)। इसलिए हम आम तौर पर इस तरह के कुछ दानेदार जगह में अपवाद को निगलना नहीं चाहते हैं और फिर एक शून्य, उदाहरण के लिए, क्योंकि इससे अपवादों के बहुत सारे मूल्य और उद्देश्य को हराया जाएगा। इसके बजाए हम उन साइटों पर अपवादों को प्रचारित करना चाहते हैं जहां हम अर्थपूर्ण तरीके से इसका सामना कर सकते हैं।


मैं पैरामीटर ए शून्य नहीं है या नहीं, यह देखने के लिए Objects.requireNonNull() का उपयोग करना पसंद करूंगा। तो यह स्पष्ट है जब आप कोड पढ़ते हैं कि पैरामीटर शून्य नहीं होना चाहिए।

और चेक अपवादों से बचने के लिए मैं CloneNotSupportedException को CloneNotSupportedException रूप में फेंक CloneNotSupportedException

दोनों के लिए आप इरादे से अच्छा टेक्स्ट जोड़ सकते हैं क्यों ऐसा नहीं होना चाहिए या मामला होना चाहिए।

public Object getClone(Object a) {

    Objects.requireNonNull(a);

    try {
        return a.clone();
    } catch (CloneNotSupportedException e) {
        throw new IllegalArgumentException(e);
    }

}

यह निश्चित रूप से पहुंचा जा सकता है। ध्यान दें कि आप केवल catch खंड में स्टैकट्रैक प्रिंट कर रहे हैं।

परिदृश्य में जहां a != null और एक अपवाद होगा, return null पहुंच जाएगा । आप उस कथन को हटा सकते हैं और इसे throw new TotallyFooException(); को throw new TotallyFooException();

सामान्य रूप से * , यदि null एक विधि का वैध परिणाम है (यानी उपयोगकर्ता इसकी अपेक्षा करता है और इसका मतलब कुछ है) तो इसे "डेटा नहीं मिला" या अपवाद के लिए सिग्नल के रूप में वापस करना एक अच्छा विचार नहीं है। अन्यथा, मुझे कोई समस्या नहीं दिख रही है कि आपको null वापस क्यों नहीं करना चाहिए।

उदाहरण के लिए Scanner#ioException विधि लें:

इस स्कैनर के अंतर्निहित पढ़ने योग्य द्वारा फेंक दिया गया IOException लौटाता है। यदि कोई ऐसा अपवाद मौजूद नहीं है तो यह विधि शून्य हो जाती है

इस मामले में, लौटा मूल्य null का स्पष्ट अर्थ होता है, जब मैं विधि का उपयोग करता हूं, तो मैं यह सुनिश्चित कर सकता हूं कि मुझे केवल null मिला क्योंकि ऐसा कोई अपवाद नहीं था और इसलिए नहीं कि विधि ने कुछ करने की कोशिश की और यह असफल रहा।

* ध्यान दें कि कभी-कभी आप संदिग्ध होने पर भी null वापस करना चाहते हैं। उदाहरण के लिए HashMap#get :

शून्य के वापसी मूल्य से यह संकेत नहीं मिलता है कि मानचित्र में कुंजी के लिए कोई मैपिंग नहीं है; यह भी संभव है कि नक्शा स्पष्ट रूप से कुंजी को शून्य पर चिह्नित करता है । इन दो मामलों को अलग करने के लिए containsKey ऑपरेशन का उपयोग किया जा सकता है।

इस मामले में null इंगित कर सकता है कि मान null पाया गया था और लौटाया गया था, या हैशैप में अनुरोधित कुंजी नहीं है।


एक अतिरिक्त वापसी कथन के बिना एक स्पष्ट तरीका इस प्रकार है। मैं CloneNotSupportedException भी नहीं CloneNotSupportedException , लेकिन इसे कॉलर पर जाने दें।

if (a != null) {
    try {
        return a.clone();
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
}
throw new TotallyFooException();

शुरुआत में आपके मुकाबले जितना अधिक सीधा-आगे वाक्यविन्यास समाप्त होता है, उस क्रम के साथ समाप्त करना लगभग हमेशा संभव होता है।


उपरोक्त उदाहरण वैध और बहुत जावा हैं। हालांकि, यहां बताया गया है कि मैं उस वापसी को संभालने के तरीके पर ओपी के प्रश्न को कैसे संबोधित करूंगा:

public Object getClone(Cloneable a) throws CloneNotSupportedException {
    return a.clone();
}

यह देखने के लिए कोई लाभ नहीं है कि यह शून्य है या नहीं। यह एनपीई जा रहा है। एक स्टैक ट्रेस प्रिंट करना भी सहायक नहीं है। स्टैक ट्रेस वही है जहां पर इसे संभाला जाता है।

अनुपयोगी नल परीक्षण और अनुपयोगी अपवाद हैंडलिंग के साथ कोड को जंक करने का कोई फायदा नहीं है। जंक को हटाकर, रिटर्न इश्यू म्यूट है।

(ध्यान दें कि ओपी में अपवाद हैंडलिंग में एक बग शामिल है; यही कारण है कि वापसी की आवश्यकता थी। ओपी को प्रस्तावित विधि को गलत नहीं मिला होगा।)


यह 'वाक्यविन्यास को संतुष्ट करने के लिए' नहीं है। यह भाषा की एक अर्थपूर्ण आवश्यकता है कि प्रत्येक कोड पथ वापसी या फेंक देता है। यह कोड अनुपालन नहीं करता है। अगर अपवाद पकड़ा जाता है तो निम्नलिखित रिटर्न की आवश्यकता होती है।

इसके बारे में कोई 'बुरा अभ्यास', या सामान्य रूप से संकलक को संतुष्ट करने के बारे में।

किसी भी मामले में, चाहे वाक्यविन्यास या अर्थपूर्ण, आपके पास इसके बारे में कोई विकल्प नहीं है।


सिंटैक्स खराब अभ्यास को पूरा करने के लिए सिर्फ एक वापसी बयान है?

जैसा कि अन्य ने उल्लेख किया है, आपके मामले में यह वास्तव में लागू नहीं होता है।

सवाल का जवाब देने के लिए, हालांकि, लिंट प्रकार के कार्यक्रमों ने निश्चित रूप से इसे समझ नहीं लिया है! मैंने स्विच स्टेटमेंट में इस पर दो अलग-अलग लोगों से लड़ने को देखा है।

    switch (var)
   {
     case A:
       break;
     default:
       return;
       break;    // Unreachable code.  Coding standard violation?
   }

एक ने शिकायत की कि ब्रेक नहीं होने के कारण कोडिंग मानक उल्लंघन था। दूसरी ने शिकायत की कि यह एक था क्योंकि यह पहुंच योग्य कोड था।

मैंने यह देखा क्योंकि दो अलग-अलग प्रोग्रामर ने ब्रेक के साथ कोड को दोबारा जांचना जारी रखा, फिर हटा दिया गया, फिर हटा दिया गया, इस पर निर्भर करता है कि उस दिन कौन सा कोड विश्लेषक भाग गया था।

यदि आप इस स्थिति में समाप्त होते हैं, तो एक चुनें और विसंगति पर टिप्पणी करें, जो कि आप स्वयं को दिखाए गए अच्छे रूप हैं। यह सबसे अच्छा और सबसे महत्वपूर्ण टेकवे है।


आपने CloneNotSupportedException पकड़ा है जिसका अर्थ है कि आपका कोड इसे संभाल सकता है। लेकिन इसे पकड़ने के बाद, आपको सचमुच पता नहीं है कि जब आप फ़ंक्शन के अंत तक पहुंचते हैं तो क्या करना है, जिसका अर्थ है कि आप इसे संभाल नहीं सकते। तो आप सही हैं कि यह इस मामले में एक कोड गंध है, और मेरे विचार में मतलब है कि आपको CloneNotSupportedException नहीं पकड़ा जाना चाहिए था।


इस तरह की स्थिति में मैं लिखूंगा

public Object getClone(SomeInterface a) throws TotallyFooException {
    // Precondition: "a" should be null or should have a someMethod method that
    // does not throw a SomeException.
    if (a == null) {
        throw new TotallyFooException() ; }
    else {
        try {
            return a.someMethod(); }
        catch (SomeException e) {
            throw new IllegalArgumentException(e) ; } }
}

दिलचस्प बात यह है कि आप कहते हैं कि "कोशिश कथन कभी विफल नहीं होगा", लेकिन आपने अभी भी एक कथन e.printStackTrace(); लिखने में परेशानी ली है e.printStackTrace(); कि आप दावा करते हैं कि कभी भी निष्पादित नहीं किया जाएगा। क्यूं कर?

शायद आपकी धारणा दृढ़ता से आयोजित नहीं है। यह अच्छा है (मेरी राय में), क्योंकि आपकी धारणा आपके द्वारा लिखे गए कोड पर आधारित नहीं है, बल्कि अपेक्षा की जाती है कि आपका ग्राहक पूर्व शर्त का उल्लंघन नहीं करेगा। सार्वजनिक तरीकों से रक्षात्मक तरीके से कार्यक्रम के लिए बेहतर है।

वैसे, आपका कोड मेरे लिए संकलित नहीं होगा। आप a.clone() करने योग्य होने के बावजूद a.clone() कॉल नहीं कर सकते हैं। कम से कम एक्लिप्स का कंपाइलर ऐसा कहता है। अभिव्यक्ति a.clone() त्रुटि देता है

विधि क्लोन () क्लोनबल प्रकार के लिए अपरिभाषित है

मैं आपके विशिष्ट मामले के लिए क्या करूंगा

public Object getClone(PubliclyCloneable a) throws TotallyFooException {
    if (a == null) {
        throw new TotallyFooException(); }
    else {
        return a.clone(); }
}

जहां PubliclyCloneable से PubliclyCloneable परिभाषित किया जाता है

interface PubliclyCloneable {
    public Object clone() ;
}

या, यदि आपको पूरी तरह से Cloneable होने के लिए पैरामीटर प्रकार की आवश्यकता है, तो कम से कम संकलित करें।

public static Object getClone(Cloneable a) throws TotallyFooException {
//  Precondition: "a" should be null or point to an object that can be cloned without
// throwing any checked exception.
    if (a == null) {
        throw new TotallyFooException(); }
    else {
        try {
            return a.getClass().getMethod("clone").invoke(a) ; }
        catch( IllegalAccessException e ) {
            throw new AssertionError(null, e) ; }
        catch( InvocationTargetException e ) {
            Throwable t = e.getTargetException() ;
            if( t instanceof Error ) {
                // Unchecked exceptions are bubbled
                throw (Error) t ; }
            else if( t instanceof RuntimeException ) {
                // Unchecked exceptions are bubbled
                throw (RuntimeException) t ; }
            else {
                // Checked exceptions indicate a precondition violation.
                throw new IllegalArgumentException(t) ; } }
        catch( NoSuchMethodException e ) {
            throw new AssertionError(null, e) ; } }
}

मैं अंत में वापसी के लिए इसे फिर से लिखूंगा। स्यूडोकोड:

if a == null throw ...
// else not needed, if this is reached, a is not null
Object b
try {
  b = a.clone
}
catch ...

return b




try-catch