জাভা -8 এ একাধিক ব্যতিক্রম ধরা


71

মাল্টি-ক্যাচ বৈশিষ্ট্যটি চেষ্টা করার সময় আমি আমার m1()পদ্ধতিতে পেয়েছি প্রত্যাশা অনুযায়ী সবকিছু ঠিকঠাকভাবে কাজ করছে।

তবে, m2()একই কোডটি সংকলন করে না। কোডের লাইনের সংখ্যা হ্রাস করতে আমি কেবল বাক্য গঠন পরিবর্তন করেছি।

public class Main {

    public int m1(boolean bool) {
        try {
            if (bool) {
                throw new Excep1();
            }
            throw new Excep2();
            //This m1() is compiling  abs fine.
        } catch (Excep1 | Excep2 e) {
            return 0;
        }
    }

    public int m2(boolean b) {
        try {
            throw b ? new Excep1() : new Excep2();
            //This one is not compiling.
        } catch (Excep1 | Excep2 e) {
            return 0;
        }
    }

    private static interface I {
    }

    private static class Excep1 extends Exception implements I {
    }

    private static class Excep2 extends Exception implements I {
    }
}

পদ্ধতিটি m2()সংকলন করে না কেন ?


22
কোন সংকলনের ত্রুটি পাচ্ছেন?
গ্যাভিন

উত্তর:


79

ভাবের ধরণ

b ? new Excep1() : new Excep2()

এটি Exceptionযেহেতু এটি সাধারণ সুপারটাইপ Excep1এবং Excep2

তবে আপনি ধরছেন না Exception, তাই সংকলক এটি সম্পর্কে অভিযোগ করে।

আপনি যদি ধরেন তবে Exceptionএটি সংকলনটি পাস করবে:

public int m2(boolean b) {
    try {
        throw b ? new Excep1() : new Excep2();
    } catch (Exception e) {
        return 0;
    }
}

আমি জেএলএস এন্ট্রিটি সন্ধান করার চেষ্টা করেছি যা আপনার উদাহরণে শর্তসাপূর্ণ ত্রৈমাসিক প্রকাশের ধরণের ব্যাখ্যা করে।

কেবলমাত্র আমি খুঁজে পেলাম যে এই নির্দিষ্ট প্রকাশটি একটি 15.25.3 is রেফারেন্স শর্তসাপেক্ষ এক্সপ্রেশন

এটি সম্পূর্ণরূপে নিশ্চিত নই যে এটি কোনও পলি এক্সপ্রেশন বা স্বতন্ত্র এক্সপ্রেশন হিসাবে গণ্য হয়। আমি মনে করি এটি এককভাবে রয়েছে (যেহেতু বহু প্রকাশের মধ্যে একটি কার্যনির্বাহী প্রসঙ্গ বা একটি আহবান প্রসঙ্গে জড়িত, এবং আমি মনে করি না যে কোনও throwবিবৃতি সেগুলির মধ্যে দুটি হিসাবে গণ্য হয়েছে)।

স্বতন্ত্র প্রকাশের জন্য: "যদি দ্বিতীয় এবং তৃতীয় অপারেন্ডগুলির একই ধরণের (যা নাল টাইপ হতে পারে) থাকে তবে তা শর্তাধীন অভিব্যক্তির ধরণ" "

আপনার ক্ষেত্রে, দ্বিতীয় ও তৃতীয় operands তিন সাধারণ ধরনের আছে - Object, Throwableএবং Exception- মত প্রকাশের ধরণ পরেরটির দুই এক হতে হবে, যেহেতু "একটি থ্রো বিবৃতিতে এক্সপ্রেশন পারেন একটি পরিবর্তনশীল বা একটি রেফারেন্স টাইপ মান বোঝাতে আবশ্যক যা থ্রোয়েবল টাইপকে নির্ধারিত (§5.2) হয়। "

এটি উপস্থিত হয় যে সংকলকটি সুনির্দিষ্ট সাধারণ ধরণের ( Exception) পছন্দ করে এবং তাই catch (Exception e)সংকলনের ত্রুটি সমাধান করে।

আমি আপনার দুটি কাস্টম ব্যতিক্রম দুটি উপ-শ্রেণীর সাথেও প্রতিস্থাপন করার চেষ্টা করেছি IOException, catch (IOException e)সেক্ষেত্রে সংকলনের ত্রুটি সমাধান করে।


11
@ স্নিগ্ধ ত্রৈমাসিকের শর্তসাপেক্ষ প্রকাশের ধরণটি ২ য় এবং তৃতীয় অপারেটরের উভয়েরই সাধারণ হতে হবে। সুতরাং এটি হতে পারে Excep1বা হয় না Excep2। এটা শুধুমাত্র হতে পারে Exception
ইরান

2
15.25.3 এ চূড়ান্ত বুলেট পয়েন্টটির উত্তর রয়েছে: "অন্যথায়, দ্বিতীয় এবং তৃতীয় অপারেশনগুলি যথাক্রমে এস 1 এবং এস 2 ধরণের হয় T এস 2-তে বক্সিং রূপান্তর প্রয়োগ করা থেকে। এখানে টিউবটি হ'ল সর্বনিম্ন উচ্চতম বাউন্ড, যা দুটি এক্সপ্রেশনর ধরণের ভাগের নিকটতম সাধারণ সুপারটাইপ।
অমলয়

22

আপনি এই লাইনের সাথে সংকলককে বিভ্রান্ত করছেন:

throw b ? new Excep1() : new Excep2();

সংকলকটি দেখেছে যে এক্সপ্রেশনটির ফলাফল (নিক্ষেপের বাম দিকে) ব্যতিক্রম ব্যতীত ব্যতিক্রম 1 এবং ব্যাতিক্রম 2 এর মধ্যে সাধারণ সুপার বর্গ যা ব্যতিক্রম, এবং তাই কার্যকরভাবে আপনি ছুঁড়ে ফেলছেন ব্যতিক্রম হয়। ক্যাচ স্টেটমেন্টটি তুলতে পারে না যে আপনি Excep1 বা Excep2 ছোঁড়ার চেষ্টা করছেন।


4

জাভা আপনাকে সমস্ত ব্যতিক্রম ধরণের পদ্ধতিগুলি ছুঁড়ে ফেলতে বা ধরতে বাধা দিতে বাধা দেয়,

এটি উভয় (/ সমস্ত) ব্যতিক্রমের জন্য সাধারণ পিতামাতার জন্য অনুসন্ধান করে এবং আপনি ছোঁড়া হিসাবে ধরা বা ঘোষণা করার প্রত্যাশা করে, উদাহরণস্বরূপ যদি Excep1প্রসারিত হয় তবে Throwableআপনাকে থ্রোয়েবলও ধরতে হবে

প্রথম ক্ষেত্রে জাভা নিশ্চিত যে আপনি হয় নিক্ষেপ করছেন Excep1বা হয়Excep2

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.