'উদাহরণস্বরূপ' অপারেটর ইন্টারফেস এবং ক্লাসগুলির জন্য আলাদা আচরণ করে


88

আমি instanceofজাভাতে অপারেটরের নিম্নলিখিত আচরণ সম্পর্কে জানতে চাই ।

interface C {}

class B {}

public class A {
    public static void main(String args[]) {
        B obj = new B();
        System.out.println(obj instanceof A);      //Gives compiler error
        System.out.println(obj instanceof C);      //Gives false as output
    }
}

এটা এমন কেন? সেখানে সম্পর্ক নেই interface Cএবং class B, কিন্তু এটা ক্ষেত্রে যেহেতু মিথ্যা দেয় obj instanceof Aএটা কম্পাইলার এরর দেয়?


12
দ্রষ্টব্য: আপনি যদি এটিতে পরিবর্তন করেন তবে Object obj = new B()এটি সংকলন করে।
ব্যবহারকারী 253751

4
সংকলক ত্রুটি আপনাকে কী বলে?
করফাউ

যদি class Bহয় finalতবে obj instanceof Cতা সংকলন করবে না, কারণ যদি Bকোনও উপপ্রকার নাও থাকতে পারে, তবে এটির সাথে সম্পর্কযুক্ত থাকার নিশ্চয়তা দেওয়া হচ্ছে C
jaco0646

উত্তর:


127

যেহেতু জাভাটির একাধিক শ্রেণীর উত্তরাধিকার নেই এটি সংকলনের সময় একেবারে জানা যায় যে objটাইপের অবজেক্টটি Bসাব টাইপ হতে পারে না A। অন্যদিকে এটি সম্ভবত ইন্টারফেসের সাব টাইপ হতে পারে C, উদাহরণস্বরূপ এই ক্ষেত্রে:

interface C {}

class B {}

class D extends B implements C {}

public class A {
    public static void main(String args[]) {
        B obj = new D();
        System.out.println(obj instanceof C);      //compiles and gives true as output  
    }
}

সুতরাং শুধুমাত্র obj instanceof Cএক্সপ্রেশন সংকলকের দিকে তাকানো এটি সত্য বা মিথ্যা হবে কিনা তা আগেই বলতে পারে না, তবে obj instanceof Aএটির দিকে তাকানো জানে যে এটি সর্বদা মিথ্যা, এভাবে অর্থহীন এবং কোনও ত্রুটি রোধ করতে আপনাকে সহায়তা করে। আপনি যদি এখনও আপনার প্রোগ্রামটিতে এই অর্থহীন চেক রাখতে চান তবে আপনি এতে একটি স্পষ্ট castালাই যুক্ত করতে পারেন Object:

System.out.println(((Object)obj) instanceof A);      //compiles fine

4
একটি অর্থহীন চেকের অন্যান্য গন্ধ ব্যবহার করাA.class.isAssignableFrom(obj.getClass())
ডেভিড Ehrmann

আমি আপনার ব্যাখ্যার সাথে কিছুটা বিভ্রান্ত হয়ে Java has no multiple class inheritanceপড়েছি আপনি বলেছেন হ্যাঁ আমি সম্মত তবে এই ক্ষেত্রে কীভাবে এটি প্রয়োগ করা হয় কারণ বি বা এ দুটিই কোনও প্রকার প্রসারিত করে না কেন এখানে একাধিক উত্তরাধিকার কেন? আপনি যদি ব্যাখ্যা করতে পারেন তবে এটি সহায়ক হবে?
কোডগ্যাসার

@ কোডডেসমার দেরী উত্তর: জাভা যদি কোনও শ্রেণিকে অন্য একাধিক শ্রেণির উত্তরাধিকার সূত্রে অনুমতি দেয় তবে কেউ "ক্লাস ডি প্রসারিত করে A, B" বা এরকম কিছু করতে পারে এবং তারপরে "বিজেট = নতুন ডি ()" তৈরি করতে পারে এবং "আপত্তি" তৈরি করতে পারে উদাহরণস্বরূপ এ "মূল প্রশ্নটি সংকলনে (যদিও এটি বর্তমানে নেই) - প্রকৃতপক্ষে এটি আরও ভাল সংকলন করেছিল, কারণ এটি সত্য থেকে মূল্যায়ন করা আশা করা হবে। তবে যদি এটিকে কেবল বি এবং এ উভয়ই হিসাবে গ্রহণের অনুমতি না দেওয়া হয় তবে "আপত্তি উদাহরণ এ" এর অভিব্যক্তি যেখানে প্রকার বি হিসাবে সংজ্ঞায়িত করা হয়েছে তা যুক্তিযুক্ত বিবেচনা করা যেতে পারে।
এমজওয়াচ

"যদি আপনি এখনও এই অর্থহীন চেক করতে চান" - এটি অর্থহীন হওয়ার দরকার নেই, যেমন এই ক্লাসগুলি অন্য লাইব্রেরি / কাঠামোর থেকে হয় তবে সম্ভাবনা রয়েছে যে আপনি রানটাইমের সময় বিভিন্ন সংস্করণ ব্যবহার করবেন B extends A। আমার জীবনে আমার আসলে যেমন অদ্ভুত চেক এবং ক্যাসেটগুলি করা দরকার যেমন (A)(Object)bরানটাইমের সময় এটি সত্যই সম্ভব ছিল।
গোটোফাইনাল

1

finalনীচের ক্লাস ঘোষণায় সংশোধক ব্যবহার করে , এটি গ্যারান্টিযুক্ত যে কোনও সাবক্লাস থাকতে পারে না Test, যা ইন্টারফেস প্রয়োগ করতে পারে Foobar। এই ক্ষেত্রে, এটি সুস্পষ্ট যে Testএবং Foobarএকে অপরের সাথে সামঞ্জস্যপূর্ণ নয়:

public final class Test {

    public static void main(String[] args) {
        Test test = new Test();
        System.out.println(test instanceof Foobar); // Compiler error: incompatible types
    }
}

interface Foobar {
}

অন্যথায়, যদি Testএটি ঘোষণা না করা হয় final, তবে এটি সম্ভবত সম্ভব যে একটি সাবক্লাস Testইন্টারফেস প্রয়োগ করে। এবং এজন্যই সংকলক test instanceof Foobarএই ক্ষেত্রে বিবৃতিটিকে অনুমতি দেবে ।

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