অ্যাক্সেসযোগ্য কোডে নতুন রানটাইম এক্সেক্সসেশন নিক্ষেপ করা কি একটি খারাপ স্টাইল?


31

আমাকে আরও দক্ষ বিকাশকারীদের দ্বারা কিছু সময় আগে লিখিত একটি আবেদন বজায় রাখার জন্য নিযুক্ত করা হয়েছিল। আমি কোডের এই অংশটি পেরিয়ে এসেছি:

public Configuration retrieveUserMailConfiguration(Long id) throws MailException {
        try {
            return translate(mailManagementService.retrieveUserMailConfiguration(id));
        } catch (Exception e) {
            rethrow(e);
        }
        throw new RuntimeException("cannot reach here");
    }

আমি উত্সাহী যদি নিক্ষেপ RuntimeException("cannot reach here")ন্যায়সঙ্গত হয়। এই কোডের টুকরোটি আরও পাকা সহকর্মীর কাছ থেকে এসেছে তা জেনে আমি সম্ভবত স্পষ্ট কিছু মিস করছি।
সম্পাদনা: এখানে পুনর্বিবেচনা বডি যা কিছু উত্তর উল্লেখ করেছে। আমি এই প্রশ্নের গুরুত্বপূর্ণ মনে করি না।

private void rethrow(Exception e) throws MailException {
        if (e instanceof InvalidDataException) {
            InvalidDataException ex = (InvalidDataException) e;
            rethrow(ex);
        }
        if (e instanceof EntityAlreadyExistsException) {
            EntityAlreadyExistsException ex = (EntityAlreadyExistsException) e;
            rethrow(ex);
        }
        if (e instanceof EntityNotFoundException) {
            EntityNotFoundException ex = (EntityNotFoundException) e;
            rethrow(ex);
        }
        if (e instanceof NoPermissionException) {
            NoPermissionException ex = (NoPermissionException) e;
            rethrow(ex);
        }
        if (e instanceof ServiceUnavailableException) {
            ServiceUnavailableException ex = (ServiceUnavailableException) e;
            rethrow(ex);
        }
        LOG.error("internal error, original exception", e);
        throw new MailUnexpectedException();
    }


private void rethrow(ServiceUnavailableException e) throws
            MailServiceUnavailableException {
        throw new MailServiceUnavailableException();
    }

private void rethrow(NoPermissionException e) throws PersonNotAuthorizedException {
    throw new PersonNotAuthorizedException();
}

private void rethrow(InvalidDataException e) throws
        MailInvalidIdException, MailLoginNotAvailableException,
        MailInvalidLoginException, MailInvalidPasswordException,
        MailInvalidEmailException {
    switch (e.getDetail()) {
        case ID_INVALID:
            throw new MailInvalidIdException();
        case LOGIN_INVALID:
            throw new MailInvalidLoginException();
        case LOGIN_NOT_ALLOWED:
            throw new MailLoginNotAvailableException();
        case PASSWORD_INVALID:
            throw new MailInvalidPasswordException();
        case EMAIL_INVALID:
            throw new MailInvalidEmailException();
    }
}

private void rethrow(EntityAlreadyExistsException e)
        throws MailLoginNotAvailableException, MailEmailAddressAlreadyForwardedToException {
    switch (e.getDetail()) {
        case LOGIN_ALREADY_TAKEN:
            throw new MailLoginNotAvailableException();
        case EMAIL_ADDRESS_ALREADY_FORWARDED_TO:
            throw new MailEmailAddressAlreadyForwardedToException();
    }
}

private void rethrow(EntityNotFoundException e) throws
        MailAccountNotCreatedException,
        MailAliasNotCreatedException {
    switch (e.getDetail()) {
        case ACCOUNT_NOT_FOUND:
            throw new MailAccountNotCreatedException();
        case ALIAS_NOT_FOUND:
            throw new MailAliasNotCreatedException();
    }
}

12
এটি প্রযুক্তিগতভাবে পৌঁছনীয়, যদি ব্যতিক্রম rethrowআসলে ব্যর্থ হয় throw। (যা বাস্তবায়ন পরিবর্তন হলে কোনও দিন ঘটতে পারে)
njzk2

34
অন্যদিকে, একটি AssertionError রানটাইম এক্সেকশন চেয়ে শব্দার্থগতভাবে ভাল পছন্দ হতে পারে।
জেভিআর

1
চূড়ান্ত নিক্ষিপ্ত হয়। আপনি যদি ফাইন্ডব্যাগ বা অন্যান্য স্থিতিশীল বিশ্লেষণ সরঞ্জামগুলি সক্ষম করেন তবে এটি অপসারণের জন্য এই ধরণের লাইনটিকে পতাকাঙ্কিত করবে।
বন আমি

7
এখন আমি বাকি কোডটি দেখতে পাচ্ছি, আমি ভাবছি যে আপনার "আরও দক্ষ বিকাশকারী" কে "আরও সিনিয়র বিকাশকারী" হিসাবে পরিবর্তন করা উচিত into কোড পর্যালোচনা কেন তা ব্যাখ্যা করে খুশি হবে।
জেভিআর

3
ব্যতিক্রম কেন ভয়ংকর তা নিয়ে আমি অনুমানমূলক উদাহরণ তৈরি করার চেষ্টা করেছি। তবে আমি এর আগে যা কিছু করেছি তা এটিতে একটি মোমবাতি ধারণ করে না।
পল ড্রাগার

উত্তর:


36

প্রথমে, আপনার প্রশ্নটি উদ্বোধনের জন্য এবং আমাদের কী rethrowকরে তা দেখানোর জন্য ধন্যবাদ । সুতরাং, প্রকৃতপক্ষে, এটি যা করে তা হ'ল ব্যাক্তিগত বৈশিষ্ট্যগুলি ব্যতিক্রমকে আরও ব্যতীত জরিমানা-গ্রেড শ্রেণিতে রূপান্তরিত করে। এই সম্পর্কে আরও পরে।

যেহেতু আমি মূল প্রশ্নের মূল উত্তরটিই দেয়নি, এখানে এটি যায়: হ্যাঁ, অ্যাক্সেসযোগ্য কোডে রানটাইম ব্যতিক্রমগুলি ছড়িয়ে দেওয়া সাধারণত খারাপ স্টাইল; সমস্যাটি এড়াতে আপনি আরও ভাল দাবি বা আরও ভাল ব্যবহার করতে চাইবেন। ইতিমধ্যে নির্দেশিত হিসাবে, এখানে সংকলক নিশ্চিত হতে পারে না যে কোডটি কখনই try/catchব্লকের বাইরে চলে না । আপনি এই সুবিধাটি গ্রহণ করে আপনার কোডটি রিফ্যাক্টর করতে পারেন ...

ত্রুটিগুলি মান

(আশ্চর্যজনকভাবে, এটি সর্বদা সুপরিচিত )

আসুন একটি সহজ উদাহরণ ব্যবহার করুন, আমি আপনার সম্পাদনার আগে যা ব্যবহার করেছি: তাই কল্পনা করুন যে আপনি কোনও লগইন করছেন এবং কোনরাদের উত্তরের মতো একটি মোড়ক ব্যতিক্রম তৈরি করছেন । এটি কল করুন logAndWrap

এর ব্যতিক্রমকে পার্শ্ব-প্রতিক্রিয়া হিসাবে ছুঁড়ে ফেলার পরিবর্তে logAndWrapআপনি এটিকে তার পার্শ্ব-প্রতিক্রিয়া হিসাবে কাজ করতে দিতে এবং এটিকে একটি ব্যতিক্রম ফিরিয়ে আনতে পারেন (কমপক্ষে, ইনপুটটিতে দেওয়া একটি)। আপনার জেনেরিকগুলি ব্যবহার করার দরকার নেই, কেবলমাত্র প্রাথমিক কার্যাদি:

private Exception logAndWrap(Exception exception) {
    // or whatever it actually does
    Log.e("Ouch! " + exception.getMessage());
    return new CustomWrapperException(exception);
}

তারপরে, আপনি throwস্পষ্টতই, এবং আপনার সংকলকটি খুশি:

try {
     return translate(mailManagementService.retrieveUserMailConfiguration(id));
} catch (Exception e) {
     throw logAndWrap(e);
}

ভুলে গেলে কি হবে throw?

জো 23-এর মন্তব্যে যেমন ব্যাখ্যা করা হয়েছে , ব্যতিক্রম সর্বদা নিক্ষেপ করা হয় তা নিশ্চিত করার জন্য একটি রক্ষণাত্মক প্রোগ্রামিংয়ের পদ্ধতিটি স্পষ্টতই throw new CustomWrapperException(exception)শেষের দিকে একটি কাজ করার অন্তর্ভুক্ত ছিল logAndWrap, কারণ এটি গুয়ারা.থ্রোয়েবালস দ্বারা করা হয়েছে । এইভাবে, আপনি জানেন যে ব্যতিক্রম নিক্ষেপ করা হবে, এবং আপনার টাইপ বিশ্লেষক খুশি। তবে, আপনার কাস্টম ব্যতিক্রমগুলি চেক করা ব্যতিক্রমগুলি হওয়া দরকার, যা সর্বদা সম্ভব হয় না। এছাড়াও, আমি কোনও throwবিকাশকারীকে নিখোঁজ হওয়ার ঝুঁকিটি খুব কম লিখতে হবে: বিকাশকারীকে অবশ্যই এটি ভুলে যেতে হবে এবং আশেপাশের পদ্ধতিতে কোনও কিছুই ফেরত দেওয়া উচিত নয়, অন্যথায় সংকলকটি অনুপস্থিত রিটার্ন সনাক্ত করতে পারে। এটি টাইপ সিস্টেমের সাথে লড়াই করার একটি আকর্ষণীয় উপায় এবং এটি কার্যকর হয়।

Rethrow

আসলটি rethrowএকটি ফাংশন হিসাবেও লেখা যেতে পারে তবে এর বর্তমান প্রয়োগে আমার সমস্যা আছে:

  • অনেকগুলি অকেজো কাস্ট রয়েছে জাতগুলি বাস্তবে প্রয়োজনীয় (মন্তব্যগুলি দেখুন):

    if (e instanceof ServiceUnavailableException) {
        ServiceUnavailableException ex = (ServiceUnavailableException) e;
        rethrow(ex);
    }
  • নতুন ব্যতিক্রম ছোঁড়া / ফিরানোর সময়, পুরানোটি বাদ দেওয়া হয়; নিম্নলিখিত কোডটিতে একটি MailLoginNotAvailableExceptionআমাকে কোন লগইন উপলভ্য নয়, কোনটি অসুবিধে করছে তা জানতে অনুমতি দেয় না; তদুপরি, স্ট্যাকট্রেসগুলি অসম্পূর্ণ হবে:

    private void rethrow(EntityAlreadyExistsException e)
        throws MailLoginNotAvailableException, MailEmailAddressAlreadyForwardedToException {
        switch (e.getDetail()) {
            case LOGIN_ALREADY_TAKEN:
                throw new MailLoginNotAvailableException();
            case EMAIL_ADDRESS_ALREADY_FORWARDED_TO:
                throw new MailEmailAddressAlreadyForwardedToException();
        }
    }
  • কেন উত্স কোডটি বিশেষায়িত ব্যতিক্রমগুলিকে প্রথম স্থানে ছুঁড়ে না ফেলে? আমার সন্দেহ হয় যে rethrowকোনও (মেলিং) সাবসিস্টেম এবং ব্যাসনেস লজিকের মধ্যে সামঞ্জস্যতা স্তর হিসাবে ব্যবহৃত হয় (সম্ভবত উদ্দেশ্যটি হ'ল কাস্টম ব্যতিক্রমগুলি দ্বারা প্রতিস্থাপনের মাধ্যমে নিক্ষিপ্ত ব্যতিক্রমগুলির মতো বাস্তবায়ন বিবরণগুলি গোপন করা)। এমনকি যদি আমি সম্মত হয়েছি যে পিট বেকারের উত্তরে প্রস্তাবিত হিসাবে ক্যাচ-ফ্রি কোড রাখা ভাল তবে আমি মনে করি না যে এখানে বড় অকার্যকরতা ছাড়াই আপনার কোড catchএবং rethrowকোড সরিয়ে দেওয়ার সুযোগ থাকবে ।


1
কাস্টগুলি অকেজো নয়। এগুলি প্রয়োজনীয়, কারণ যুক্তির ধরণের ভিত্তিতে কোনও গতিশীল প্রেরণ নেই। সঠিক পদ্ধতিতে কল করতে সংকলনের সময় আর্গুমেন্টের ধরণটি অবশ্যই জানা উচিত।
জো 23

আপনার logAndWrapপদ্ধতিতে আপনি ব্যতিক্রমটি এটির পরিবর্তে ফেলে দিতে পারেন, তবে ফেরতের ধরণটি রাখুন (Runtime)Exception। এইভাবে ক্যাচ ব্লকটি আপনি যেভাবে লিখেছেন তা অবধি থাকতে পারে (অ্যাক্সেসযোগ্য কোডে থ্রো ছাড়াই)। তবে এর অতিরিক্ত সুবিধা রয়েছে যা আপনি ভুলে যেতে পারবেন না throw। আপনি যদি ব্যতিক্রমটি ফিরিয়ে দেন এবং নিক্ষেপ ভুলে যান তবে ব্যতিক্রমটি নিঃশব্দে গ্রাস করা হবে। রিটার্ন টাইপ রানটাইম এক্সেপশন থাকার সময় নিক্ষেপ করা এই ত্রুটিগুলি এড়িয়ে গিয়ে সংকলককে খুশি করবে। এভাবেই পেয়ারা Throwables.propagateপ্রয়োগ করা হয়।
জো 23

@ জো 23 স্ট্যাটিক প্রেরণের বিষয়ে স্পষ্টতার জন্য ধন্যবাদ। ফাংশনের অভ্যন্তরে ব্যতিক্রম ছোঁড়া সম্পর্কে: আপনি কি বোঝাতে চেয়েছেন যে সম্ভাব্য ত্রুটিটি আপনি বর্ণনা করছেন এমন ক্যাচ ব্লক যা কল করে logAndWrapকিন্তু প্রত্যাবর্তিত ব্যতিক্রম ছাড়া কিছুই করে না? এটি চমৎকার. কোনও ফাংশনের অভ্যন্তরে অবশ্যই কোনও মান ফেরত দিতে হবে, সংকলকটি লক্ষ্য করবে যে কোনও পাথ নেই যার সাথে কোনও মূল্য ফেরানো হয় না, তবে এটি এমন পদ্ধতির জন্য কার্যকর যা কোনও কিছুই ফেরত দেয় না। আবার ধন্যবাদ.
coredump

1
আমি ঠিক এটাই করি। এবং কেবল এই বিষয়টিকে আবার চাপ দেওয়ার জন্য: এটি এমন কিছু নয় যা আমি এনেছি এবং এর জন্য creditণ গ্রহণ করি না, তবে পেয়ারা উত্স থেকে আটকানো হয়।
জো 23

@ Joe23 আমি গ্রন্থাগার একটি সুনির্দিষ্ট রেফারেন্স যোগ
coredump

52

এই rethrow(e);ফাংশনটি নীতির লঙ্ঘন করে যা বলে যে সাধারণ পরিস্থিতিতে, একটি ফাংশন ফিরে আসবে, যখন ব্যতিক্রমী পরিস্থিতিতে একটি ফাংশন ব্যতিক্রম ছুঁড়ে ফেলে। এই ফাংশনটি সাধারণ পরিস্থিতিতে একটি ব্যতিক্রম ছুঁড়ে দিয়ে এই নীতিটি লঙ্ঘন করে। এটাই সমস্ত বিভ্রান্তির উত্স।

সংকলকটি ধরে নিয়েছে যে এই ফাংশনটি স্বাভাবিক পরিস্থিতিতে ফিরে আসবে, তাই সংকলক যতদূর বলতে পারে, retrieveUserMailConfigurationফাংশনটির শেষের দিকে এক্সিকিউশনটি পৌঁছে যেতে পারে , যেখানে কোন বক্তব্য না রাখলে এটি ত্রুটি return। সেখানে RuntimeExceptionনিক্ষিপ্ত হওয়াটি এই সংকলকের এই উদ্বেগকে হ্রাস করার কথা, তবে এটি এটি করার একটি বরং চটকদার উপায়। function must return a valueত্রুটি প্রতিরোধের আরেকটি উপায় হ'ল একটি return null; //to keep the compiler happyবিবৃতি যুক্ত করা, তবে এটি আমার মতে সমানভাবে বিশৃঙ্খল।

সুতরাং, ব্যক্তিগতভাবে, আমি এটি প্রতিস্থাপন করব:

rethrow(e);

এর সাথে:

report(e); 
throw e;

বা, আরও ভাল, ( কর্ডাম্প পরামর্শ হিসাবে ) এটি দিয়ে:

throw reportAndTransform(e);

এইভাবে, নিয়ন্ত্রণের প্রবাহটি সংকলকের কাছে সুস্পষ্টভাবে প্রকাশিত হবে, সুতরাং আপনার চূড়ান্তটি throw new RuntimeException("cannot reach here");কেবল অপ্রয়োজনীয় হয়ে উঠবে না, তবে বাস্তবে এটি সংকলনযোগ্যও নয়, কারণ এটি সংযোজনযোগ্য কোড হিসাবে সংকলক দ্বারা পতাকাঙ্কিত হবে।

এই কুরুচিপূর্ণ পরিস্থিতি থেকে বেরিয়ে আসার এটি সবচেয়ে মার্জিত এবং প্রকৃতপক্ষে সহজতম উপায়।


1
-1 ফাংশনটিকে দুটি বিবৃতিতে বিভক্ত করার পরামর্শ খারাপ অনুলিপি / আটকানোর কারণে প্রোগ্রামিং ত্রুটির পরিচয় দিতে পারে; আমিও একটু সত্য যে আপনার প্রশ্নের সুপারিশ সম্পাদিত নিয়ে আমি চিন্তিত throw reportAndTransform(e)একটি মিনিট দম্পতি পর আমি আমার নিজের উত্তর পোস্ট করা হয়েছে। হতে পারে আপনি এটি সম্পর্কে স্বতন্ত্রভাবে প্রশ্নটি পরিবর্তন করেছেন এবং যদি তা হয় তবে আমি আগেই ক্ষমা চাইছি, তবে অন্যথায়, একটু creditণ দেওয়া লোকেরা সাধারণত এমন কিছু করে।
coredump

4
@ কর্ড্প্প আমি আসলে আপনার পরামর্শটি পড়েছিলাম এবং আমি আরও একটি উত্তর পড়েছিলাম যা এই পরামর্শটিকে আপনার কাছে বিশেষত বলে উল্লেখ করেছে এবং আমি মনে রেখেছিলাম যে আমি ইতিপূর্বে এইরকম একটি নির্মাণকে যথাযথভাবে নিযুক্ত করেছি, তাই আমি এটিকে আমার উত্তরে অন্তর্ভুক্ত করার সিদ্ধান্ত নিয়েছি। আমি ভেবেছিলাম যে এটি এতটা গুরুত্বপূর্ণ নয় যে কোনও অ্যাট্রিবিউশন অন্তর্ভুক্ত করা, কারণ আমরা এখানে একটি মূল ধারণা সম্পর্কে কথা বলছি না, তবে আপনি যদি বিষয়টি নিয়ে যান তবে আমি আপনাকে আরও বাড়িয়ে তুলতে চাই না, সুতরাং অ্যাট্রিবিউশনটি এখন আছে, একটি লিঙ্ক দিয়ে সম্পূর্ণ। চিয়ার্স।
মাইক নাকিস

এটি এই নয় যে আমার কাছে এই নির্মাণের পেটেন্ট রয়েছে, যা বেশ সাধারণ; তবে কল্পনা করুন যে আপনি একটি উত্তর লিখেছেন এবং এর খুব বেশি পরে নয়, এটি অন্য একটি দ্বারা "আত্তীকরণ" হয়। সুতরাং এট্রিবিউশনটি অনেক প্রশংসাযোগ্য। ধন্যবাদ.
coredump

3
ফাংশনটি যা ফিরে আসে না তাতে সেয়ে কোনও ভুল নেই। এটি সর্বদা ঘটে থাকে, উদাহরণস্বরূপ, রিয়েল-টাইম সিস্টেমে। চূড়ান্ত সমস্যাটি জাভাতে একটি ত্রুটি যা ভাষা বিশ্লেষণ করে এবং ভাষাগুলি যথার্থতার ধারণাটি কার্যকর করে এবং তবুও ভাষা কোনওভাবে ফাংশন ফিরে না আসে এমন মন্তব্য করার জন্য কোনও ব্যবস্থা সরবরাহ করে না। যাইহোক, নকশা নিদর্শন যে, এই যেমন কাছাকাছি পেতে হয় throw reportAndTransform(e)। অনেকগুলি নকশার নিদর্শনগুলি হ'ল প্যাচগুলি ভাষার বৈশিষ্ট্যগুলি অনুপস্থিত। এই হল তাদের একজন।
ডেভিড হামেন

2
অন্যদিকে, অনেক আধুনিক ভাষা যথেষ্ট জটিল। প্রতিটি নকশার প্যাটার্নটিকে মূল ভাষার বৈশিষ্ট্যে রূপান্তর করা তাদের আরও ফুলে উঠবে। এটি একটি নকশার প্যাটার্নের একটি ভাল উদাহরণ যা মূল ভাষায় অন্তর্ভুক্ত নয়। যেমনটি লেখা হয়েছে, এটি কেবল সংকলক দ্বারা নয়, কোড পার্স করতে হবে এমন আরও অনেক সরঞ্জাম দ্বারা ভালভাবে বোঝা গেছে।
MSalters

7

throwসম্ভবত "পদ্ধতি কোন মান ফিরিয়ে আবশ্যক" কাছাকাছি পেতে ত্রুটি অন্যথায় ঘটবে জোড়া হয়েছে - জাভা তথ্য প্রবাহ বিশ্লেষক স্মার্ট বুঝতে কোনো যথেষ্ট returnপরে প্রয়োজনীয় throw, কিন্তু না আপনার কাস্টম পর rethrow()পদ্ধতি, এবং সেখানে নেই @NoReturnটীকা আপনি এটি ঠিক করতে ব্যবহার করতে পারেন যে।

তবুও, অ্যাক্সেসযোগ্য কোডে একটি নতুন ব্যতিক্রম তৈরি করা অতিরিক্ত প্রয়োজন বলে মনে হচ্ছে। আমি কেবল লিখব return null, জেনেও যে এটি আসলে ঘটে না।


তুমি ঠিক. আমি throw new...লাইনটি মন্তব্য করলে কী হবে তা আমি পরীক্ষা করেছিলাম এবং এটি কোনও রিটার্নের বিবৃতি না দেওয়ার বিষয়ে অভিযোগ করে। এটা কি খারাপ প্রোগ্রামিং? কোন অ্যাক্সেসযোগ্য রিটার্ন স্টেটমেন্ট প্রতিস্থাপন সম্পর্কে কোনও সম্মেলন আছে? আরও ইনপুটকে উত্সাহিত করার জন্য আমি এই প্রশ্নের উত্তর না দিয়ে কিছুক্ষণ রেখে দেব। তবুও আপনার উত্তরের জন্য ধন্যবাদ।
সোক পোমারানজজি

3
@ সোকপোমারানকজোয়ে হ্যাঁ, এটি খারাপ প্রোগ্রামিং। এই rethrow()পদ্ধতিটি catchব্যতিক্রমটিকে নতুন করে তুলছে তা এই সত্যটি লুকিয়ে রাখে । আমি এমন কিছু করা এড়াতে চাই। অবশ্যই, অবশ্যই, rethrow()ব্যতিক্রমটি পুনর্বিবেচনা করতে ব্যর্থ হতে পারে, যার ক্ষেত্রে অন্য কিছু ঘটে।
রস প্যাটারসন

26
দয়া করে ব্যতিক্রমটি প্রতিস্থাপন করবেন না return null। ব্যতিক্রম সহ, ভবিষ্যতে যদি কেউ কোডটি ভেঙে দেয় তবে শেষ লাইনটি কীভাবে পৌঁছতে পারে তা ব্যতিক্রম ছুঁড়ে ফেলা হলে তা অবিলম্বে পরিষ্কার হয়ে যাবে। আপনি যদি এর পরিবর্তে হন তবে return nullএখন nullআপনার অ্যাপ্লিকেশনটিতে এমন একটি মান রয়েছে যা প্রত্যাশিত ছিল না। কে জানে আবেদনে কোথায় NullPointerExceptionউত্থাপিত হবে? আপনি ভাগ্যবান না হলে এবং এই ফাংশনটিতে কল করার পরে এটি মধ্যস্থতাকারী না হলে আসল সমস্যাটি খুঁজে পাওয়া খুব কঠিন হবে।
আনহোলিস্যাম্পলার 14

5
@ ম্যাথেরিডে অ্যাক্সেসযোগ্য কোডের প্রয়োগ কার্যকর করা একটি তীব্র বাগ, return nullএটি সম্ভবত বাগটি মাস্ক করার সম্ভাবনা রয়েছে কারণ আপনি nullএই বাগ থেকে ফিরে আসা অন্যান্য ক্ষেত্রে আলাদা করতে পারবেন না ।
কোডসইনচাউস

4
তদ্ব্যতীত, যদি ফাংশনটি ইতিমধ্যে কিছু পরিস্থিতিতে নালায় ফিরে আসে এবং আপনিও এই পরিস্থিতিতে নাল রিটার্ন ব্যবহার করেন, তবে ব্যবহারকারীরা এখন নাল রিটার্ন পেলে তাদের মধ্যে থাকতে পারে এমন দুটি সম্ভাব্য পরিস্থিতি রয়েছে। কখনও কখনও এটি গুরুত্বপূর্ণ নয়, কারণ নাল রিটার্নটির অর্থ ইতিমধ্যে "কোনও বস্তু নেই এবং আমি কেন তা নির্দিষ্ট করে দিচ্ছি না", সুতরাং সামান্য তাত্পর্যপূর্ণ হওয়ার জন্য আরও একটি সম্ভাব্য কারণ যুক্ত করা। তবে প্রায়শই অস্পষ্টতা যুক্ত করা খারাপ, এবং এর অবশ্যই অর্থ হ'ল তাত্ক্ষণিকভাবে "এটি ভাঙ্গা" এর মতো দেখার পরিবর্তে বাগগুলি প্রথমে "নির্দিষ্ট পরিস্থিতিতে" বলে বিবেচিত হবে। তাড়াতাড়ি ব্যর্থ।
স্টিভ জেসোপ

6

দ্য

throw new RuntimeException("cannot reach here");

বিবৃতি এটি একটি সুস্পষ্ট ভাবে জানিয়ে দিচ্ছেন PERSON কে , কোড কি হচ্ছে পড়া, যাতে ভাল তারপর উদাহরণস্বরূপ নাল ফিরে অনেক। কোডটি অপ্রত্যাশিতভাবে পরিবর্তিত হলে ডিবাগ করাও সহজ করে তোলে make

তবে rethrow(e)শুধু ভুল মনে হচ্ছে! সুতরাং আপনার ক্ষেত্রে আমি মনে করি কোডটি রিফ্যাক্ট করা একটি ভাল বিকল্প। আপনার কোডটি বাছাই করার জন্য অন্যান্য উত্তরগুলি (আমার কাছে করডাম্পের সেরা পছন্দ) দেখুন।


4

আমি জানি না কোন সম্মেলন আছে কিনা।

যাইহোক, অন্য কৌশল এর মতো করতে হবে:

private <T> T rethrow(Exception exception) {
    // or whatever it actually does
    Log.e("Ouch! " + exception.getMessage());
    throw new CustomWrapperException(exception);
}

এটির জন্য অনুমতি দেওয়া:

try {
     return translate(mailManagementService.retrieveUserMailConfiguration(id));
} catch (Exception e) {
     return rethrow(e);
}

আর কোনও কৃত্রিমের RuntimeExceptionদরকার নেই। যদিও rethrowআসলে কখনই কোনও মান ফেরত দেয় না, এটি এখন কম্পাইলারের পক্ষে যথেষ্ট ভাল।

এটি তত্ত্বের (পদ্ধতির স্বাক্ষর) কোনও মূল্য ফেরত দেয় এবং তারপরে এটির পরিবর্তে ব্যতিক্রম ছুঁড়ে দেওয়ার পরে এটি আসলে এটি থেকে অব্যাহতি পায়।

হ্যাঁ, এটিকে দেখতে অদ্ভুত লাগবে, তবে আবার - কোনও কাহিনী নিক্ষেপ করা RuntimeException, বা শূন্যস্থান ফিরে আসা যা এই পৃথিবীতে আর কখনও দেখা যাবে না - এটি ঠিক সৌন্দর্যের বিষয় নয়।

পঠনযোগ্যতার জন্য প্রচেষ্টা করে আপনি নাম পরিবর্তন rethrowকরতে পারেন এবং এর মতো কিছু থাকতে পারেন:

} catch (Exception e) {
     return nothingJustRethrow(e);
}

2

আপনি যদি tryব্লকটি পুরোপুরি সরিয়ে ফেলেন তবে আপনার প্রয়োজন নেই rethrowবা throw। এই কোডটি মূল হিসাবে ঠিক একই জিনিস করে:

public Configuration retrieveUserMailConfiguration(Long id) throws MailException {
    return translate(mailManagementService.retrieveUserMailConfiguration(id));
}

এটি আরও পাকা বিকাশকারীদের কাছ থেকে আসা সত্যটি আপনাকে বোকা বানাবেন না। এটি কোড পচা, এবং এটি সর্বদা ঘটে। শুধু এটি ঠিক করুন।

সম্পাদনা: আমি rethrow(e)ব্যতিক্রমটিকে পুনরায় ছুঁড়ে ফেলার মত ভুল পাঠ করেছি e। যদি সেই rethrowপদ্ধতিটি ব্যতিক্রমটিকে পুনরায় নিক্ষেপ করা ব্যতীত অন্য কিছু করে, তবে এ থেকে মুক্তি পাওয়া এই পদ্ধতির শব্দার্থকে পরিবর্তন করে change


লোকেরা বিশ্বাস করতে থাকবে যে ওয়াইল্ডকার্ড ক্যাচগুলি যা কিছুই হ্যান্ডেল করে না তা আসলে ব্যতিক্রম হ্যান্ডলার exception আপনার সংস্করণটি যা পরিচালনা করতে পারে না তা পরিচালনা করার ভান করে ত্রুটিযুক্ত অনুমানটিকে অগ্রাহ্য করে। পুনরুদ্ধারকারীর ব্যবহারকারীমেল কনফিগারেশন () এর কলকারী কিছু ফিরে পাওয়ার আশা করে। যদি এই ফাংশনটি যুক্তিসঙ্গত কিছু ফিরিয়ে দিতে না পারে তবে দ্রুত এবং জোরে ব্যর্থ হওয়া উচিত। দেখে মনে হচ্ছে অন্য উত্তরগুলি এমন কোনও সমস্যা দেখেনি catch(Exception)যা একটি ঘৃণ্য কোড-গন্ধ।
এমএসডাব্লু

1
@ এমএসডাব্লু - কার্গো-কাল্ট কোডিং।
পিট বেকার 21

@ এমএসডাব্লু - অন্যদিকে, এটি আপনাকে ব্রেকপয়েন্ট নির্ধারণের জায়গা দেয়।
পিট বেকার 21

1
আপনি যদি যুক্তিটির পুরো অংশকে ছাড়ানোর কোনও সমস্যা দেখতে না পান তবে এটি হ'ল। আপনার সংস্করণ স্পষ্টতই আসলটির মতো একই কাজ করে না, যা ইতিমধ্যে দ্রুত এবং জোরে ব্যর্থ। আমি আপনার উত্তরের মতো ক্যাচ-ফ্রি পদ্ধতি লিখতে পছন্দ করব তবে বিদ্যমান কোডের সাথে কাজ করার সময়, আমাদের অন্যান্য কার্যকরী অংশগুলির সাথে চুক্তিগুলি ভাঙ্গা উচিত নয়। এটি হতে পারে যে যা করা হয় তা rethrowঅকেজো (এবং এটি এখানে বিন্দু নয়) তবে আপনি যে কোডটি পছন্দ করেন না কেবল তা থেকে মুক্তি পেতে পারেন না এবং এটি স্পষ্টভাবে না থাকলে এটি মূল হিসাবে সমান বলে দিতে পারেন say কাস্টম rethrowফাংশনে পার্শ্ব-প্রতিক্রিয়া রয়েছে ।
coredump

1
@ jpmc26 প্রশ্নের মূল বিষয়টি "এখানে পৌঁছাতে পারে না" ব্যতিক্রম সম্পর্কে, যা পূর্ববর্তী চেষ্টা / ক্যাচ ব্লককে বাদ দিয়ে অন্যান্য কারণে উত্থিত হতে পারে। তবে আমি সম্মত হলাম যে ব্লকটি মৎস্য গন্ধযুক্ত, এবং যদি এই উত্তরটি প্রাথমিকভাবে আরও যত্ন সহকারে বলা হয়, তবে এটি আরও অনেকগুলি উপার্জন করতে পারত (আমি বিটিডব্লু ডাউন করি নি)। শেষ সম্পাদনাটি ভাল।
coredump
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.