কোনও সম্পর্কযুক্ত ইন্টারফেস প্রকারের সাথে অনুরোধ করার সময় সংকলক শ্রেণীর ধরণের পরামিতিগুলির সাথে কেন এই জেনেরিক পদ্ধতিটি বেছে নেয়?


11

নিম্নলিখিত দুটি ক্লাস এবং ইন্টারফেস বিবেচনা করুন:

public class Class1 {}
public class Class2 {}
public interface Interface1 {}

দ্বিতীয় কল কেন mandatoryওভারলোডেড পদ্ধতিটির সাথে অনুরোধ জানায় Class2, যদি getInterface1এবং এর Interface1সাথে কোনও সম্পর্ক না থাকে Class2?

public class Test {

    public static void main(String[] args) {
        Class1 class1 = getClass1();
        Interface1 interface1 = getInterface1();

        mandatory(getClass1());     // prints "T is not class2"
        mandatory(getInterface1()); // prints "T is class2"
        mandatory(class1);          // prints "T is not class2"
        mandatory(interface1);      // prints "T is not class2"
    }

    public static <T> void mandatory(T o) {
        System.out.println("T is not class2");
    }

    public static <T extends Class2> void mandatory(T o) {
        System.out.println("T is class2");
    }

    public static <T extends Class1> T getClass1() {
        return null;
    }

    public static <T extends Interface1> T getInterface1() {
        return null;
    }
}

আমি বুঝতে পারি যে জাভা 8 জাভা 7 এর সাথে সামঞ্জস্যতা ভঙ্গ করেছে :

$ /usr/lib/jvm/java-8-openjdk-amd64/bin/javac -source 1.7 -target 1.7 *java; /usr/lib/jvm/java-8-openjdk-amd64/bin/java Test
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
T is not class2
T is not class2
T is not class2
T is not class2

এবং জাভা 8 দিয়ে (11 এবং 13 দিয়ে পরীক্ষাও করা হয়েছে):

$ /usr/lib/jvm/java-8-openjdk-amd64/bin/javac *java; /usr/lib/jvm/java-8-openjdk-amd64/bin/java Test                        
T is not class2
T is class2
T is not class2
T is not class2

1
নীচের লাইন: জাভাতে পদ্ধতি ওভারলোডিং এত বিস্ময় নিয়ে আসে, এটি কেবলমাত্র চরম যত্ন সহ ব্যবহার করা উচিত। উত্তরের জটিলতা দ্বারা প্রদর্শিত হিসাবে, কেবলমাত্র টাইপ প্যারামিটারের একটি গণ্ডি দিয়ে দুটি ওভারলোডকে বৈষম্যমূলক আচরণ জিজ্ঞাসা করছে। আপনি মূলত আপনার কোডের প্রতিটি পাঠককে আপনার কোডটি বোঝার আগে সেই উত্তরটি পড়তে এবং বুঝতে জিজ্ঞাসা করছেন। অন্যভাবে বলুন: টাইপ অনুমানটি উন্নত করার সময় যদি আপনার প্রোগ্রামটি ভেঙে যায় তবে আপনি নিরাপদ অঞ্চলে নেই। শুভকামনা!
স্টিফান হার্মান

উত্তর:


4

টাইপ আনফারেন্সের নিয়মগুলি জাভা 8-তে একটি উল্লেখযোগ্য ওভারহল পেয়েছে, সর্বাধিক উল্লেখযোগ্যভাবে লক্ষ্য প্রকারের অনুক্রমটি অনেক উন্নত হয়েছে। সুতরাং, জাভা 8 এর আগে পদ্ধতির যুক্তি সাইটটি কোনও অনুকরণ প্রাপ্তি করে না, মুছে ফেলা ধরণের ( Class1জন্য getClass1()এবং তার Interface1জন্য getInterface1()) ডিফল্ট করে , জাভা 8-এ সর্বাধিক নির্দিষ্ট প্রযোজ্য প্রকারটি অনুমান করা হয়। জাভা 8 এর জন্য জেএলএস একটি নতুন অধ্যায় অধ্যায় 18 চালু করেছে Java


এর জন্য সুনির্দিষ্ট প্রযোজ্য প্রকারটি <T extends Interface1>হ'ল <X extends RequiredClass & BottomInterface>, যেখানে RequiredClassপ্রসঙ্গ দ্বারা প্রয়োজনীয় শ্রেণি প্রয়োজন, এবং BottomInterfaceসমস্ত ইন্টারফেসের (সহ Interface1) নীচের প্রকার type

নোট: প্রতিটি জাভা টাইপ হিসাবে প্রতিনিধিত্ব করা যেতে পারে SomeClass & SomeInterfaces। যেহেতু RequiredClassউপ-প্রকার SomeClass, এবং BottomInterfaceউপ-প্রকার SomeInterfaces, Xযে জাভা ধরনের উপ-প্রকার। সুতরাং, Xএকটি জাভা নীচের ধরনের।

Xউভয় public static <T> void mandatory(T o)এবং public static <T extends Class2> void mandatory(T o)পদ্ধতি স্বাক্ষরের Xসাথে জাভা নীচের প্রকারের সাথে মেলে ।

সুতরাং, অনুযায়ী §15.12.2 , mandatory(getInterface1())অধিকাংশ নির্দিষ্ট ওভারলোডিং আহ্বান mandatory()পদ্ধতি, যা public static <T extends Class2> void mandatory(T o)থেকে <T extends Class2>চেয়ে বেশি নির্দিষ্ট <T>

পদ্ধতির স্বাক্ষরের সাথে getInterface1()মেলে এমন ফলাফলটি ফেরত দেওয়ার জন্য আপনি কীভাবে স্পষ্টভাবে টাইপ পরামিতি নির্দিষ্ট করতে পারেন public static <T extends Class2> void mandatory(T o):

public static <T extends Class2 & Interface1> void helper() {
    mandatory(Test.<T>getInterface1()); // prints "T is class2"
}

সর্বাধিক নির্দিষ্ট প্রযোজ্য প্রকারটি <T extends Class1>হ'ল <Y extends Class1 & BottomInterface>, যেখানে BottomInterfaceসমস্ত ইন্টারফেসের জন্য নীচের ধরণ।

Yম্যাচ public static <T> void mandatory(T o)পদ্ধতি স্বাক্ষর, কিন্তু এটা মেলে না public static <T extends Class2> void mandatory(T o)পদ্ধতি স্বাক্ষর যেহেতু Yপ্রযোজ্য না Class2

সুতরাং mandatory(getClass1())কল public static <T> void mandatory(T o)পদ্ধতি।

এর বিপরীতে getInterface1(), আপনি পদ্ধতির স্বাক্ষরের সাথে getClass1()মেলে এমন ফলাফলটি ফেরত দিতে আপনি স্পষ্টভাবে টাইপ পরামিতি নির্দিষ্ট করতে পারবেন না public static <T extends Class2> void mandatory(T o):

                       java: interface expected here
                                     
public static <T extends Class1 & C̲l̲a̲s̲s̲2> void helper() {
    mandatory(Test.<T>getClass1());
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.